问题
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.
回答1:
is there any case where using out keyword in the above example makes any difference?
Nope. You're allowed to specify out
in the declaration, you just won't ever be able to actually leverage it when dealing with a specific instance of that type.
Nothing about this program doesn't work properly, so you're essentially asking for a feature request of the compiler prohibiting this behavior as it is a likely indication of a mistake on the part of the developer. The response to that request is (just like virtually any other feature request) that Microsoft either didn't consider this as an option, or if they did, determined that it wasn't worth the time and effort to actively prohibit this behavior.
来源:https://stackoverflow.com/questions/16739249/why-does-this-covariance-declaration-compile