8

当我们在 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.

还,

这不是Java在相同情况下所做的吗?据我记得,你只是做类似的事情

IMyInterface<? extends whatever> myInterface; //covariance
IMyInterface<? super whatever> myInterface2; //contravariance

还是我在混合东西?

谢谢

4

2 回答 2

8

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

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

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

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

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

于 2010-04-29T00:26:22.657 回答
0

好的,这是我所问的答案(来自 Eric 的回答):http: //blogs.msdn.com/ericlippert/archive/2007/10/29/covariance-and-contravariance-in-c-part-seven-为什么我们需要一个语法at-all.aspx

首先,在我看来,差异应该是你故意设计到你的界面或委托中的东西。让它在不受用户控制的情况下开始发生,这与该目标背道而驰,并且还可能引入破坏性更改。(更多关于那些在以后的帖子!)

自动这样做也意味着随着开发过程的进行以及向接口添加方法,接口的变化可能会发生意想不到的变化。这可能会在该计划的其他地方引入意想不到且影响深远的变化。

我决定在这里明确提出,因为尽管他的链接确实有我问题的答案,但帖子本身却没有。

于 2010-04-29T00:40:18.357 回答