diff --git a/docs/standard/generics/covariance-and-contravariance.md b/docs/standard/generics/covariance-and-contravariance.md index db5aa04d30fa9..ab9ebbf65e76f 100644 --- a/docs/standard/generics/covariance-and-contravariance.md +++ b/docs/standard/generics/covariance-and-contravariance.md @@ -1,7 +1,8 @@ --- title: "Covariance and Contravariance in Generics" description: Learn about covariance, which allows you to use a more derived type, and contravariance, which allows you to use a less derived type, in .NET generics. -ms.date: "03/30/2017" +ms.date: "03/09/2026" +ai-usage: ai-assisted dev_langs: - "csharp" - "vb" @@ -14,27 +15,21 @@ ms.assetid: 2678dc63-c7f9-4590-9ddc-0a4df684d42e --- # Covariance and contravariance in generics -*Covariance* and *contravariance* are terms that refer to the ability to use a more derived type (more specific) or a less derived type (less specific) than originally specified. Generic type parameters support covariance and contravariance to provide greater flexibility in assigning and using generic types. +*Covariance* and *contravariance* describe how reference conversions work between constructed generic types when their type arguments are related by inheritance, for example, between `IEnumerable` and `IEnumerable`. Variance is a property of a generic interface or delegate type's type parameter, and it controls which implicit conversions exist between constructed types that use different type arguments. By default, generic type parameters are *invariant*—even if one type argument derives from another, the corresponding constructed generic types, such as `List` and `List`, are unrelated unless the type parameter is explicitly declared as *covariant* or *contravariant*. -When you're referring to a type system, covariance, contravariance, and invariance have the following definitions. The examples assume a base class named `Base` and a derived class named `Derived`. - -- `Covariance` - - Enables you to use a more derived type than originally specified. - - You can assign an instance of `IEnumerable` to a variable of type `IEnumerable`. - -- `Contravariance` - - Enables you to use a more generic (less derived) type than originally specified. - - You can assign an instance of `Action` to a variable of type `Action`. - -- `Invariance` - - Means that you can use only the type originally specified. An invariant generic type parameter is neither covariant nor contravariant. - - You cannot assign an instance of `List` to a variable of type `List` or vice versa. +The following definitions and examples assume a base class named `Base` and a derived class named `Derived`. + +- *Invariant* type arguments require you to use exactly the type specified. You can't substitute a derived or base type. + + For example, you can't assign an instance of `List` to a variable of type `List`, or vice versa. + +- *Covariant* type parameters let you substitute a more derived type for the original type argument. + + For example, you can assign an instance of `IEnumerable` to a variable of type `IEnumerable`. + +- *Contravariant* type parameters let you substitute a base type for a derived type argument instead of the original. + + For example, you can assign an instance of `Action` to a variable of type `Action`. Covariant type parameters enable you to make assignments that look much like ordinary [Polymorphism](../../csharp/fundamentals/object-oriented/polymorphism.md), as shown in the following code.