简体   繁体   中英

Create a User-Defined Convertion for Generic Type

I am trying to create a Cacheable object. My problem is that I want to allow the Cacheable object to directly convert it to T. I am trying to overide operator explicitly/implicitly but I'm still receiving the InvalidCastException. Here is my Cacheable object

public class Cacheable<T> : ICacheable<T>, IEquatable<T>
{
    private Func<T> fetch;
    private T value { get; set; }

    public Cacheable(Func<T> fetch)
    {
        this.fetch = fetch;
    }

    public T Value
    {
        get
        {
            if (value == null) value = fetch();

            return value;
        }
    }

    public bool Equals(T other)
    {
        return other.Equals(Value);
    }

    public void Source(Func<T> fetch)
    {
        this.fetch = fetch;
    }

    public static implicit operator Cacheable<T>(Func<T> source)
    {
        return new Cacheable<T>(source);
    }

    public static explicit operator Func<T>(Cacheable<T> cacheable)
    {
        return cacheable.fetch;
    }

    public static explicit operator T(Cacheable<T> cacheable)
    {
        return cacheable.Value;
    }
}

and this is the code I am trying to use

public class prog
{
    public string sample()
    {
        var principal = new Cacheable<IPrincipal>(()=>{
             var user = HttpContext.Current.User;
             if (!user.Identity.IsAuthenticated) throw new UnauthorizedAccessException();
             return user;
        });

        return ((IPrincipal)principal).Identity.Name; //this is where the error occur
    }
}

Error Info:

An exception of type 'System.InvalidCastException' occurred in Connect.Service.dll but was not handled in user code

Additional information: Unable to cast object of type 'Common.Cacheable`1[System.Security.Principal.IPrincipal]' to type 'System.Security.Principal.IPrincipal'.

Explicite conversion does not Work when one of both values is a Interface you can read this here: https://msdn.microsoft.com/en-us/library/aa664464(VS.71).aspx

To bring you program to work you need a Class that inherits from IPrincipal and cast like this:

return ((YourPrincipal)principal).Identity.Name;

This link shows you how to create your own Principal.

https://msdn.microsoft.com/en-us/library/ff649210.aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM