方差不适用于具有引用类型的代理

时间:2010-10-01 16:43:07

标签: c# .net c#-4.0

a)编译

        Func<string, bool> f1 = (Func<object, bool>)null;

b)不

        Func<int, bool> f2 = (Func<object, bool>)null;

为什么值类型在这里很特别?是否违反了价值类型?

1 个答案:

答案 0 :(得分:6)

通用方差仅适用于引用类型,是的。 (这是因为CLR知道所有内容仍然只是一个引用,所以JITted代码仍然是相同的......引用中涉及的位与您所讨论的任何类型相同,而处理int由于object需要装箱转换。基本上,您可以将representational identity与参考类型保持一致。)

从C#4规范,第13.1.3.2节:

  

如果T是使用变体类型参数T<A1, …, An>声明的接口或委托类型,并且对于每个变体类型参数,则类型T<B1, …, Bn>可以变量转换为类型T<X1, …, Xn> Xi以下之一:

     
      
  • Xi是协变的,从Ai到Bi
  • 存在隐式参考或身份转换   
  • Xi是逆变的,从Bi到Ai
  • 存在隐式参考或身份转换   
  • Xi是不变的,并且从Ai到Bi
  • 存在身份转换   

这是“隐式引用转换”,而不仅仅是“隐式转换”位,这是值类型的问题。

关于很多关于泛型方差的更多细节,请参阅Eric Lippert的blog series on the topic