2010-04-28 30 views
8

当我们在C#4.0中定义接口时,我们可以将每个通用参数标记为inout。如果我们试图设置一个泛型参数并导致问题,编译器会提出一个错误,而不允许我们这样做。C#4.0中的协变和逆变推断

问:

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

例子:

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 

或者我混合的东西?

感谢

回答

8

如果编译器推断的方法有哪些两个协方差(出)和逆变(中)有效的用途,为什么我们必须标记接口,这样的?

我不太确定我是否理解这个问题。我想你在问两件事。

1)编译器能否推导出方差注释?

and

2)为什么C#不支持像Java那样的调用站点差异?

这个问题的答案首先是:

interface IRezrov<V, W> 
{ 
    IRezrov<V, W> Rezrov(IRezrov<W, V> x); 
} 

我邀请你试图推断出所有可能的法律差异的注释是对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 == r对于两千位素数p和q是真或假。这并不意味着很容易取r和找到p和q,使得等式得到满足。编译器可以轻松检查方差注释是正确还是不正确;这并不意味着它可以在潜在的数十亿个可能的注释中找到正确的方差注释。

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

+0

我认为他的第二个问题更像是“C#的变异注释与Java的通配符类型有什么不同?” – Gabe 2010-04-29 00:29:46

+1

@加贝:C#做*声明网站*方差。 Java不会* call-site *方差。呼叫站点差异确实是一个有趣的想法,但让我感到奇怪的是,根据特定站点上的使用方式,将类型变为变体,而不是如何定义其行为。 – 2010-04-29 00:37:18

+0

是的,我现在明白了Java使用的问题。它的好处是不需要将接口参数声明为in或out,但是现在有些客户端可能会立即给它一些使用权,如果我计划更新接口,那么以后可能不会被使用。 – 2010-04-29 00:42:27

0

OK,这里是答案,我问(从Eric的回答):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

首先,在我看来,方差 应该是东西,你 故意设计到您的 接口或代表。使其只是 开始发生而不受 用户的控制,并且 也可以引入重大更改。 (对那些在以后的文章更 !)

这样做自动地也意味着 作为发展进程的推移和 方法添加到界面中, 方差接口可能会改变 意外。这可能在程序中的其他地方引入 意外和深远的变化 。

我决定把它明确地放在这里,因为虽然他的链接确实有我的问题的答案,但帖子本身并没有。