在C# 4.0中定义接口时,允许将每个泛型参数标记为in或out。如果我们试图将泛型参数设置为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.,
这不是Java在相同情况下所做的吗?据我所知,你只是做了一些事情
IMyInterface<? extends whatever> myInterface; //covariance
IMyInterface<? super whatever> myInterface2; //contravariance还是我混在一起了?
谢谢
发布于 2010-04-29 00:26:22
如果编译器有推断协方差(out)和反方差(In)的有效用途的方法,为什么我们必须将接口标记成这样呢?
我不太明白这个问题。我想你在问两件事。
( 1)编译器能推导出方差注释吗?
和
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
更笼统地说:你的问题表明了错误的推理。廉价检查解决方案是否正确的能力在逻辑上并不意味着有一种寻找正确解决方案的廉价方法。例如,对于2,000位数的素数p和q,计算机可以很容易地验证p*q == r是真还是假,这并不意味着很容易取r并找到p和q从而满足等式的要求。编译器可以很容易地检查一个方差注释是正确的还是不正确的;这并不意味着它可以在潜在的数十亿可能的注释中找到一个正确的方差注释。
第二个问题的答案是: C#不是Java。
发布于 2010-04-29 00:40:18
好的,下面是我问的问题的答案(来自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
首先,在我看来,方差应该是您有意在接口或委托中设计的东西。让它在没有用户控制的情况下刚刚开始发生,就违背了这个目标,而且还可以引入破坏性的更改。(稍后会有更多的报道!)
这样做也意味着,随着开发过程的继续,方法被添加到接口中,接口的变化可能会意外地发生变化。这可能会在项目的其他地方带来意想不到的影响深远的变化。
我决定在这里明确指出,因为虽然他的链接确实回答了我的问题,但帖子本身却没有。
https://stackoverflow.com/questions/2733388
复制相似问题