具有多个参数的Func方差

Car*_*rra 5 c# func covariance

在我们的代码中尝试了类似的东西,但它失败了:

Func<Employee, Employee> _myFunc;

void Main()
{
    Func<Employee, Employee> test1  = _myFunc;//Ok
    Func<Employee, Person> test2  = _myFunc;//Ok
    Func<Person, Employee> test3 = _myFunc;//Fails
    Func<Person, Person> test4  = _myFunc;//Fails
}

public class Person { }
public class Employee : Person { }
Run Code Online (Sandbox Code Playgroud)

最后两个案例给出了这个错误:

无法隐式转换System.Func<Employee, Employee>System.Func<Person, Employee>.存在显式转换(您是否错过了演员?)

知道为什么吗?

Yuv*_*kov 12

如果你查看签名Func<T, TResult>,你会看到输入参数(T在这种情况下)是逆变的,返回类型(TResult)是协变的

public delegate TResult Func<in T, out TResult>(T arg);
Run Code Online (Sandbox Code Playgroud)

逆变量基本上是关于能够将"更大"类型传递给期望"更小"类型的方法,其中协方差恰恰相反.

埃里克·利珀特( Eric Lippert )非常优雅(强调我的):

如果具有引用类型参数的构造保留赋值兼容性的方向,则泛型类型I是协变的(在T中).如果它颠倒了赋值兼容性的方向,则它是逆变的(在T中).如果两者都没有,那就是不变的.通过这种方式,我们只是简单地说,采用T并产生I的投影是协变/逆变/不变投影.

  • @ haim770我不认为这就是Eric的意思.我假设他的意思是通用类型`I <T>`是T*中的协变/逆变*,意味着每个`T`. (2认同)
  • 这就是我的意思,但我同意我写它的方式很混乱!遗憾的是,我不再拥有对msdn博客的写访问权. (2认同)