我有以下代码:
static Func<object, string> s_objToString = (x) => x.ToString();
static Func<string, string> s_stringToString = s_objToString; //compiles
static Func<int, string> s_intToString = s_objToString; //error
第二行编译但第三行无法编译并出现错误:
无法将类型“
System.Func<object,string>
”隐式转换为“System.Func<int,string>
”
为什么?
我理解,虽然字符串是从对象派生的,但List<string>
不是从List<object>
派生的,但object
到string
的工作和object
到int
失败了,为什么?
好吧,让我说我理解为什么;现在的问题是有办法绕过它(除了将MyInt
类定义为方框int
,因为Func<object,string>
到Func<MyInt,string>
有效)?
答案 0 :(得分:5)
这是因为Func
定义为Func<in T, out TResult>
,MSDN定义为here,因此T
contra-variant {{1} }关键字,也就是说,您可以使用您指定的类型或任何派生类型较少的类型,但请记住协方差和反方差不支持值类型:
Why covariance and contravariance do not support value type
因此,它适用于in
但不适用于string
。您可能需要阅读有关协方差和逆变的更多信息:
答案 1 :(得分:3)
因为co / contra-variance对值类型不起作用。
请查看here
仅当类型参数是引用类型时才支持差异。值类型不支持差异。
以下内容不编译:
// int is a value type, so the code doesn't compile.
IEnumerable<Object> objects = new List<int>(); // Compiler error here.