从Func <object,string>到Func <string,string>的转换工作但是到Func <int,string>失败</int,string> </string,string> </object,string>

时间:2012-10-23 07:06:00

标签: c# generics covariance func contravariance

我有以下代码:

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>派生的,但objectstring的工作和objectint失败了,为什么?

好吧,让我说我理解为什么;现在的问题是有办法绕过它(除了将MyInt类定义为方框int,因为Func<object,string>Func<MyInt,string>有效)?

2 个答案:

答案 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。您可能需要阅读有关协方差和逆变的更多信息:

http://msdn.microsoft.com/en-us/library/dd233060.aspx

http://msdn.microsoft.com/en-us/library/dd799517.aspx

答案 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.