IEnumerable<T>
, IComparable<T>
and a few more are now type-variant. IList<T>
, ICollection<T>
and many others aren't. Why?
In C#, covariance and contravariance enable implicit reference conversion for array types, delegate types, and generic type arguments. Covariance preserves assignment compatibility and contravariance reverses it.
In short, type variance describes the types that may be substituted in place of another type. Covariance: We say a substitution is covariant with a type, Foo, if Foo or any other class with a subclass relationship to Foo is valid.
Covariance permits a method to have a return type that is a subtype of the one defined in the delegate. Contravariance permits a method to have a parameter type that is a base type of the one defined in the delegate type.
Covariance permits a method to have return type that is more derived than that defined in the delegate. Contravariance permits a method that has parameter types that are less derived than those in the delegate type.
.NET Framework 4.0 introduces safe co/contra-variance. IList<T>
and ICollection<T>
have T
both in input and output positions while IEnumerable<T>
has T
only in output positions and IComparable<T>
has T
only in input positions.
Assume IList<T>
supported type variance:
static void FailingMethod(IList<object> list) {
list[0] = 5;
}
static void Test() {
var a = new List<string>();
a[0] = "hello";
FailingMethod(a); // if it was variant, this method call would be unsafe
}
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