【问题标题】:Create a User-Defined Convertion for Generic Type为通用类型创建用户定义的转换
【发布时间】:2015-07-30 04:47:56
【问题描述】:

我正在尝试创建一个可缓存对象。我的问题是我想允许 Cacheable 对象直接将其转换为 T。我试图显式/隐式地覆盖运算符,但我仍然收到 InvalidCastException。 这是我的可缓存对象

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;
    }
}

这是我正在尝试使用的代码

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
    }
}

错误信息:

Connect.Service.dll 中出现“System.InvalidCastException”类型的异常,但未在用户代码中处理

附加信息:无法将“Common.Cacheable`1[System.Security.Principal.IPrincipal]”类型的对象转换为“System.Security.Principal.IPrincipal”类型。

【问题讨论】:

  • 为什么你不能只写一个方法,比如public T GetValue&lt;T&gt;(),然后从中返回Value
  • 我已经拥有该方法/公共获取属性。我只是想让开发人员能够将 cacheable 转换为 T.
  • principal.Value.Identity.Name 会起作用,我只是希望缓存能够直接转换为 T,任何来宾,还是有可能?
  • 我尝试通过覆盖隐式/显式运算符来做到这一点,但它不起作用

标签: c# generics


【解决方案1】:

当两个值之一是接口时,显式转换不起作用,您可以在此处阅读:https://msdn.microsoft.com/en-us/library/aa664464(VS.71).aspx

为了让您的程序正常工作,您需要一个继承自 IPrincipal 的类并像这样进行转换:

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

此链接向您展示如何创建自己的 Principal。

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

【讨论】:

  • 谢谢,现在很清楚了。在尝试制作此代码时。我能够转换它。 var a = Cacheable(()=> "sample"); var b = (string)a; // 'b' 获取 a.Value 的值;谢谢
  • 我也试过这个,它可以工作 var a = new Cacheable(() => HttpContext.Current); var b = (HttpContext)a;
  • @VJPPaz 你能把它标记为其他人看到它对你有帮助的遮阳篷还是自己写一个对你有用的遮阳篷?
猜你喜欢
  • 2011-04-02
  • 2013-11-27
  • 2012-07-18
  • 1970-01-01
  • 2021-05-30
  • 2012-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多