With C# generics, the compiler compiles the generic code into IL independent of any specific types the client will use. As a result, the generic code could try to use methods, properties, or members of the generic type parameters that are incompatible with the specific types the client uses. This is unacceptable, because it amounts to a lack of type safety. In C#, you need to instruct the compiler which constraints the client-specified types must obey in order for them to be used instead of the generic type parameters. There are three types of constraints, which the following sections will explore in detail:
- Derivation constraint
Indicates to the compiler that the generic type parameter derives from a base type such as an interface or a particular base class
- Default constructor constraint
Indicates to the compiler that the generic type parameter exposes a default public constructor (a public constructor with no parameters)
- Value/reference type constraint
Constrains the generic type parameter to be a value or a reference type
A generic type can employ multiple constraints, and you even get IntelliSense reflecting the constraints when using the generic type parameter (e.g., suggesting methods or members from the base type).
Note that although constraints are optional, they are often essential when developing a generic type. Without them, the compiler takes the more conservative, type-safe approach and allows access only to
object-level functionality in your generic ...