Terms
Namespace: System.GenericGeneric Type Parameters
Generic type parameters are placeholders for type arguments that are specified when a generic type or method is used. They are defined within angle brackets (<T>) after the type or method name. For example, in List<T>, T is a generic type parameter.
Type Arguments
Type arguments are the actual types that are supplied for generic type parameters when a generic type or method is instantiated. For example, when you create a List<int>, int is the type argument for the generic type parameter T.
Constraints
Constraints are rules applied to generic type parameters to restrict the types that can be used as type arguments. They ensure that the type argument supports the operations performed within the generic code. Common constraints include:
where T : struct: The type argument must be a value type.where T : class: The type argument must be a reference type.where T : new(): The type argument must have a public parameterless constructor.where T : SomeBaseClass: The type argument must be or derive fromSomeBaseClass.where T : ISomeInterface: The type argument must implementISomeInterface.- Combinations of the above.
Covariance and Contravariance
These terms relate to how generic interfaces and delegates can be subtyped. They allow for more flexible assignment of generic types:
- Covariance: Allows using a more derived type than originally specified. For example, a method returning
IEnumerable<Derived>can be assigned to a variable expectingIEnumerable<Base>(ifIEnumerable<out T>is used). The generic type parameter is marked with theoutkeyword. - Contravariance: Allows using a less derived type than originally specified. For example, a method accepting
Action<Base>can be assigned to a variable expectingAction<Derived>(ifAction<in T>is used). The generic type parameter is marked with theinkeyword.
Variance
Variance is the general term encompassing both covariance and contravariance. It allows for flexibility in the type relationships of generic parameters.
Invariant
A generic type that is neither covariant nor contravariant is considered invariant with respect to its type parameter. For example, List<T> is invariant, meaning List<Derived> cannot be assigned to a List<Base> variable.
Generic Methods
Methods that declare one or more generic type parameters. These parameters are specified within angle brackets before the method's return type. For example:
public static void Swap<T>(ref T lhs, ref T rhs) { ... }
In this example, T is a generic type parameter for the Swap method.
Generic Interfaces
Interfaces that declare one or more generic type parameters. They are used to define contracts that can operate on a variety of types without knowing them at compile time.
public interface IEnumerable<out T> : IEnumerable { ... }
Generic Delegates
Delegates that declare one or more generic type parameters. They define a method signature that can be assigned to methods with matching parameters and return types, parameterized by generic types.
public delegate void Action<in T>(T obj);