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.