当我们在C#4.0中定义接口时,我们可以将每个通用参数标记为in
或out
。如果我们试图设置一个泛型参数并导致问题,编译器会提出一个错误,而不允许我们这样做。C#4.0中的协变和逆变推断
问:
如果编译器推断的方法有哪些两个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.
此外,
是不是什么Java那样在同样的情况?从我记得,你只是做一些像
IMyInterface<? extends whatever> myInterface; //covariance
IMyInterface<? super whatever> myInterface2; //contravariance
或者我混合的东西?
感谢
我认为他的第二个问题更像是“C#的变异注释与Java的通配符类型有什么不同?” – Gabe 2010-04-29 00:29:46
@加贝:C#做*声明网站*方差。 Java不会* call-site *方差。呼叫站点差异确实是一个有趣的想法,但让我感到奇怪的是,根据特定站点上的使用方式,将类型变为变体,而不是如何定义其行为。 – 2010-04-29 00:37:18
是的,我现在明白了Java使用的问题。它的好处是不需要将接口参数声明为in或out,但是现在有些客户端可能会立即给它一些使用权,如果我计划更新接口,那么以后可能不会被使用。 – 2010-04-29 00:42:27