Variance defines subtyping between more complex types. It may be either preserved, reversed, or ignored.
Covariance
Covariance allows implicit conversion for arrays, collection and generic types.
It allows a more specific type to be placed inside less parent type.
- String stringValue = “abc”;
-
- Object objValue = stringValue;
Here, an object of a more derived type is assigned to an object of a less derived type.
Now, see Covariance example:
- IEnumerable<string> stringValues = new List<string>();
-
- IEnumerable<object> objectValues =stringValues;
Here, an object that is instantiated with a more derived type argument is assigned to an object instantiated with a less derived type argument.
And, assignment compatibility is preserved.
ContraVariance
Contravariance allows implicit conversion for arrays, collection and generic types.
It allows less parent type to be implicitly placed inside more specific type.
Let, there is a method:
- static void SetMyObject(object obj) { }
-
- Action<object> myObject = SetMyObject;
-
- Ation<string> myString = myObject;
Here, an object that is instantiated with a less derived type argument is assigned to an object instantiated with more derived type argument.
So, assignment compatibility is reversed.