7

Consider this interface:

interface Test<out T> where T : struct { }

It compiles without errors or warnings.

As discussed in this question, and mentioned in the Covariance and Contravariance FAQ:

Variance is supported only if a type parameter is a reference type.

So why does the above interface compile? It would make sense to fail (or at least warn) on the "out" keyword. I guess the question boils down to - is there any case where using out keyword in the above example makes any difference?


Update: Here's an example misleading behavior that may slip through for the unaware developer who looks at the Interface above:

typeof(IDummy).IsAssignableFrom(typeof(MyStruct)); // should return true
typeof(ITest<IDummy>).IsAssignableFrom(typeof(ITest<MyStruct>)); // returns false

If the coder isn't aware of variance not working for value types, they would expect the second line to return true - because of the out keyword - but it never will. This is exactly the bug that prompted me to ask this question...


Another example of code that would compile but produce unexpected results:

ITest<MyStruct> foo = ...;
var casted = (ITest<IDummy>)foo;

I would expect this to work (not knowing about the limitation of covariance to reference types) but it causes a System.InvalidCastException.

4

1 回答 1

2

在上面的例子中使用 out 关键字有什么不同吗?

没有。您可以out在声明中指定,但在处理该类型的特定实例时,您将永远无法实际利用它。

这个程序没有任何东西不能正常工作,所以你实际上是在要求编译器的功能请求禁止这种行为,因为这可能表明开发人员有错误。对该请求的响应是(就像几乎任何其他功能请求一样)Microsoft 要么不认为这是一个选项,要么如果他们这样做了,则确定不值得花费时间和精力来积极禁止这种行为。

于 2013-05-24T16:12:10.053 回答