« Variance » : différence entre les versions
De Banane Atomic
Aller à la navigationAller à la recherche
Ligne 6 : | Ligne 6 : | ||
= [https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/covariance-contravariance Description] = | = [https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/covariance-contravariance Description] = | ||
Variance allows to replace a type with a less-derived (covariance: derived → base) type or a more-derived type (contravariance: base → derived).<br> | Variance allows to replace a type with a less-derived (covariance: derived → base) type or a more-derived type (contravariance: base → derived).<br> | ||
* Covariance enable implicit reference conversion for array types, delegate types, and generic type arguments.<br> | * Covariance enable implicit reference conversion for array types, delegate types, and generic type arguments.<br>It preserves assignment compatibility and contravariance reverses it. | ||
* Contravariance | * Contravariance | ||
{{info | Since .NET Framework 4, C# supports covariance and contravariance in generic interfaces and delegates and allows for implicit conversion of generic type parameters.}} | {{info | Since .NET Framework 4, C# supports covariance and contravariance in generic interfaces and delegates and allows for implicit conversion of generic type parameters.}} |
Version du 27 mars 2024 à 15:50
Links
Description
Variance allows to replace a type with a less-derived (covariance: derived → base) type or a more-derived type (contravariance: base → derived).
- Covariance enable implicit reference conversion for array types, delegate types, and generic type arguments.
It preserves assignment compatibility and contravariance reverses it. - Contravariance
Since .NET Framework 4, C# supports covariance and contravariance in generic interfaces and delegates and allows for implicit conversion of generic type parameters. |
Assignment compatibility
Allow an object of a more derived type (child class, ex: string) to be assigned to an object of a less derived type (parent class, ex: object).
string s = "test"; object o = s; |
Covariance
Allow a generic object of child class type (ex: string) to be assigned to a generic object of parent class type (ex: object).
It works only with covariant interface |
var deriveds = new List<Derived>(); List<Base> bases = strings; // Cannot convert type List<Base> to List<Derived> because List<T> is invariant IList<Base> bases = strings; // Cannot implicitly convert type List<Base> to IList<Derived> because IList<T> is invariant var bases = (IList<Base>)deriveds; // at execution, Unable to cast List<Derived> to type IList<Base> IEnumerable<Base> bases = deriveds; // IEnumerable<T> is covariant IReadOnlyList<Base> bases = deriveds; // IReadOnlyList<T> is covariant IReadOnlyCollection<Base> bases = deriveds; // IReadOnlyCollection<T> is covariant |
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> { } |
Native variant interfaces
Interface | Since |
---|---|
IEnumerable<out T> | .NET Framework 4.0 |
IReadOnlyList<out T> | .NET Framework 4.5 |
IReadOnlyCollection<out T> | .NET Framework 4.5 |