SoFunction
Updated on 2025-03-07

In-depth understanding of C# generic constraints

The where clause is used to specify type constraints that can be used as variables for type parameters defined in generic declarations.
1. Interface constraints.
For example, you can declare a generic class MyGenericClass, so that the type parameter T can implement the IComparable<T> interface:
Copy the codeThe code is as follows:

public class MyGenericClass<T> where T:IComparable { }

2. Base class constraints:It indicates that a type must use the specified class as the base class (or the class itself) to be used as a type parameter for the generic type.
Once such constraints are used, they must appear before all other constraints of the parameter of the type.
Copy the codeThe code is as follows:

class MyClassy<T, U>
where T : class
where U : struct
{
}

The clause may also include constructor constraints.
You can use the new operator to create an instance of a type parameter; however, the type parameter must be bound by the constructor constraint new() for this purpose. The new() constraint lets the compiler know that any type of parameter provided must have an accessible parameterless (or default) constructor. For example:
Copy the codeThe code is as follows:

public class MyGenericClass <T> where T: IComparable, new()
{
// The following line is not possible without new() constraint:
         T item = new T();
}

The new() constraint appears at the end of the where clause.
4. For multiple type parameters, each type parameter uses a where clause
For example:
Copy the codeThe code is as follows:

interface MyI { }
class Dictionary<TKey,TVal>
where TKey: IComparable, IEnumerable
where TVal: MyI
{
public void Add(TKey key, TVal val)
{
}
}

5. You can also attach constraints to type parameters of generic methods, such as:
Copy the codeThe code is as follows:

public bool MyMethod<T>(T t) where T : IMyInterface { }

Note that for both delegates and methods, the syntax for describing type parameter constraints is the same:
Copy the codeThe code is as follows:

delegate T MyDelegate<T>() where T : new()