C#4.0中的协方差和逆变推理

dev*_*ium 8 c# java generics covariance contravariance

当我们在C#4.0中定义接口时,我们可以将每个通用参数标记为inout.如果我们尝试将泛型参数设置为out并且导致问题,则编译器会引发错误,而不允许我们这样做.

题:

如果编译器有推断两者covariance(out)和contravariance(in)的有效用途的方法,为什么我们必须将接口标记为这样?仅仅让我们像往常一样定义接口是不够的,当我们尝试在客户端代码中使用它们时,如果我们试图以不安全的方式使用它们会引发错误?

例:

interface MyInterface<out T> {
    T abracadabra();
}
//works OK

interface MyInterface2<in T> {
    T abracadabra();
}
//compiler raises an error.
//This makes me think that the compiler is cappable 
//of understanding what situations might generate 
//run-time problems and then prohibits them.
Run Code Online (Sandbox Code Playgroud)

也,

是不是Java在同样的情况下做了什么?从我记得,你只是做了类似的事情

IMyInterface<? extends whatever> myInterface; //covariance
IMyInterface<? super whatever> myInterface2; //contravariance
Run Code Online (Sandbox Code Playgroud)

还是我在混合东西?

谢谢

Eri*_*ert 8

如果编译器有推断协方差(out)和逆变量(in)的有效用途的方法,为什么我们必须将接口标记为这样?

我不太清楚我理解这个问题.我想你要问两件事.

1)编译器可以推导出方差注释吗?

2)为什么C#不像Java那样支持呼叫站点方差?

第一个答案是:

interface IRezrov<V, W> 
{
    IRezrov<V, W> Rezrov(IRezrov<W, V> x);
}
Run Code Online (Sandbox Code Playgroud)

我邀请您尝试推断V和W上所有合法可能的方差注释.您可能会感到惊讶.

如果您无法找到此方法的唯一最佳方差注释,为什么您认为编译器可以?

更多理由:

http://blogs.msdn.com/ericlippert/archive/2007/10/29/covariance-and-contravariance-in-c-part-seven-why-do-we-need-a-syntax-at-all. ASPX

更一般地说:你的问题表明了错误的推理.廉价地检查解决方案是否正确的能力在逻辑上并不意味着找到正确解决方案的廉价方法.例如,对于两千位素数p和q,计算机可以容易地验证p*q == r是真还是假.这并不意味着很容易采用r并找到p和q以满足相等性.编译器可以轻松检查方差注释是正确还是不正确; 这并不意味着它可以在潜在的数十亿可能的注释中找到正确的方差注释.

第二个答案是:C#不是Java.