I'm learning C# generics and making some dummy code for testing purposes. So, I'm testing the in Generic Modifier, which specifies that the type parameter is contravariant.
Given the below interface:
public interface IInterfaceTest<in T>
{
void Method(T value);
void Method(IList<T> values);
void Method(IEnumerable<T> values);
}
When compiling, I'm getting the error message:
[CS1961] Invalid variance: The type parameter 'T' must be invariantly valid on 'IInterfaceTest.Method(IList)'. 'T' is contravariant.
The error is related only with the line void Method(IEnumerable<T> values). If this line is removed, all works fine.
So my question is: Why can I use the generic contravariant with IEnumerable but does not with IList? Am I forgot something?
Thanks.
The question why it's not allowed for IList<T> has been answered in the comments and linked questions already: IList<T> is invariant in T and so a contra-variant T cannot be used here whatsoever.
What puzzled me at first is the fact that Method(IEnumerable<T>) is allowed here. The strange thing is that variance is "turned around" when you use the T as a type argument for another generic type.
Imagine this.
public interface ITestInterface<in T>
{
void Method(IEnumerable<T> e);
IEnumerable<T> GetMethod(); // illegal
}
public class Animal {}
public class Lion : Animal [}
public class Gnu : Animal {}
ITestInterface<Animal> animals;
ITestInterface<Lion> lions;
ITestInterface<Gnu> gnus;
Now the contra-variance of ITestInterface<in T> in T tells us that you can do
lions = animals;
And when you call lions.Method(e), you can only provide an IEnumerable<Lion>. So the code of Method can only enumerate Lions, which are all Animals as animals.Method() expects. Everything is fine.
On the other hand, the IEnumerable<T> GetMethod() is illegal, because:
gnus = animals;
is legal, and now gnu.GetMethod() would return an IEnumerable<Animal> where you'd expect an IEnumerable<Gnu>. And when you iterated, suprising animals could wait in that sequence.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With