C# 从Func转换<;对象,字符串>;to Func<;字符串,字符串>;有效,但不起作用<;int,string>;失败

C# 从Func转换<;对象,字符串>;to Func<;字符串,字符串>;有效,但不起作用<;int,string>;失败,c#,generics,covariance,func,contravariance,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 static Func s_objT

我有以下代码:

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
static Func s_objToString=(x)=>x.ToString();
静态函数s_stringToString=s_objToString//汇编
静态函数s_intToString=s_objToString//错误
第二行已编译,但第三行未能编译,出现错误:

无法将类型“
System.Func
”隐式转换为“
System.Func

这是为什么?

我了解到,在遗传学中,虽然字符串是从对象a
List
派生出来的,但不是从
List
派生出来的,但是在这里
object
string
起作用,而
object
int
失败,为什么


好吧,让我们说我明白为什么;现在的问题是有一种解决方法(除了定义
MyInt
类到box
int
因为
Func
Func
有效之外)?

因为协方差/反方差不适用于值类型

请看一看

仅当类型参数是引用类型时,才支持差异。值类型不支持差异
以下内容也不编译:

// int is a value type, so the code doesn't compile.
IEnumerable<Object> objects = new List<int>(); // Compiler error here.
//int是一种值类型,因此代码不会编译。
IEnumerable objects=新列表();//这里有编译器错误。

这是因为
Func
被定义为
Func
,MSDN是,所以
T
是与
in
关键字相反的变量,也就是说,您可以使用指定的类型或派生较少的任何类型,但请记住,协方差和反方差不支持值类型:

因此,它适用于
string
,但不适用于
int
。您可能需要阅读有关协方差和逆变换的更多信息:


查看预览中的问题总是值得的,特别是当你询问有关泛型的问题(或其他使用
尖括号的问题)时,以确保你的文本显示或相应地标记。@Roey你可以通过将
int
强制转换为
对象来框住它,(或者将其传递给
s_objToString
!),您不需要新的类来完成此操作。将其传递给
s_objToString
或将其强制转换为对象可能会有一个简单的解决方案。但我的问题是类似以下函数的问题:
public static string codeList(List thelist,Func coder)
有关详细信息,请参阅Underrent,以下内容不使用字符串static List objs=new List()编译;@RoeyNissim:概念协方差和反向方差只适用于泛型接口和委托,所以列表是不变的,而不是covariant@RoeyNissim@CuongLe:这个答案是正确的,尽管这里的例子不好。答案中的编译错误是由于从
IEnumerable
IEnumerable
本身的无效转换造成的@DannyChen:是的,这是正确的,我只是试图为@RoeyNissim解释为什么
List objs=new List()
不起作用,谢谢。有没有办法解决这个问题?除了定义MyInt类来box int,还可以使Func to Funcwork@RoeyNissim我要说的是,你应该考虑你的设计来避免这种情况。顺便说一下,你应该在这里发布另一个问题而不是更新问题来问另一个问题。