Links
Variance allows to replace a type with a less-derived (covariance: derived → base) type or a more-derived type (contravariance: base → derived).
It is available for array types, delegate types, and generic types.
Assignment compatibility
Allow an object of a more derived type (derived) to be assigned to an object of a less derived type (base).
|
Derived derived;
Base base = derived;
|
Covariance
Allow a generic object with derived type to be assigned to a generic object of base type.
 |
It works only with covariant interface |
|
var deriveds = new List<Derived>();
List<Base> bases = strings;
IList<Base> bases = strings;
var bases = (IList<Base>)deriveds;
IEnumerable<Base> bases = deriveds;
IReadOnlyList<Base> bases = deriveds;
IReadOnlyCollection<Base> bases = deriveds;
|
Create a covariant interface
|
var derivedVariants = new VariantList<Derived> { new Derived() };
IVariantList<Base> baseVariants = derivedVariants;
var derivedVariant = new Variant<Derived>();
IVariant<Base> baseVariant = derivedVariant;
interface IVariantList<out T> { }
class VariantList<T> : List<T>, IVariantList<T> { }
interface IVariant<out T> { }
class Variant<T> : IVariant<T> { }
|
Contravariance
Allow a generic object with base type to be used for a generic object of derived type.
|
class BaseComparer : IEqualityComparer<Base>
{
public bool Equals(Base? x, Base? y) => x?.Id == y?.Id;
public int GetHashCode(Base obj) => obj.Id;
}
var derived1 = new Derived { Id = 1 };
var derived1bis = new Derived { Id = 1 };
var derived2 = new Derived { Id = 2 };
var baseComparer = new BaseComparer();
var b3 = baseComparer.Equals(derived1, derived1bis);
var b4 = baseComparer.Equals(derived1, derived2);
|
Interface
|
Since
|
IEnumerable<out T> |
.NET Framework 4.0
|
IReadOnlyList<out T> |
.NET Framework 4.5
|
IReadOnlyCollection<out T> |
.NET Framework 4.5
|