a)编译
Func<string, bool> f1 = (Func<object, bool>)null;
b)不
Func<int, bool> f2 = (Func<object, bool>)null;
为什么值类型在这里很特别?是否违反了价值类型?
答案 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。