Covariance and Contravariance

  • enables implicit reference conversions for
    • arrays
    • delegates
    • generic type arguments
  • Covariance preserves assignment compatibility
  • Contravariance reverses assignment compatibility
  • allows for matching signatures of delegates and method groups
    • to assign to delegates from method that returns more derived types – covariance
    • to assign to delegates from method that returns less derived types – contravariance
  • Covariance and Contravariance are supported in Generics for implicit conversions for type parameters
    • allows method to have more derived return type than defined by generic type parameter of the interface
    • this allows implicit conversions from one generic interface to another (from IEnumerable<string> to IEnumerable<object> even if first does not inherits from second)
    • allows generic types to have less derived argument types than specified by the generic parameter of the interface (implementation of IEqualityComparer<BaseClass> can be implicitly converted to IEqualityComparer<DerivedClass> because IEqualityComparer.Equals is contravariant)
    • implicit conversions works for interfaces but not classes that implement from those interfaces (i.e. this won’t work List<Object> list = new List<String>())

Assignment compatibility is when object of a more derived type is assigned to an object of a less derived type.

object obj = str;

String can be represented as an object because it is reference type and inherits from System.Object.

Covariance is when object that is instantiated with a more derived type argument is assigned to an object instantiated with a less derived type argument.

IEnumerable<string> strings = new List<string>();

List<> inherits from IEnumerable<string> so can be represented as such.

Covariance in generic interface:

interface IEnumerable<out T>

Contravariance is when object that is instantiated with a less derived type argument is assigned to an object instantiated with a more derived type argument.

static void SetObject(object o) { }
Action<object> actObject = SetObject;  
Action<string> actString = actObject;

Contravariance in generic interface:

interface IEqualityComparer<in T>

Leave a Reply

Your email address will not be published. Required fields are marked *

Solve : *
16 + 19 =