In depth understanding of C generic constraints

  • 2020-05-12 03:09:19
  • OfStack

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

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

2. Base class constraint: indicates that a type must have the specified class as the base class (or the class itself) in order to be used as a type parameter for the generic type.
Such a constraint 1, when used, must appear before all other constraints on a parameter of that type.

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

3. The where clause can also include constructor constraints.
You can use the new operator to create instances of type parameters. However, the type parameter must be constrained by the constructor constraint new(). The new() constraint lets the compiler know that any type parameter provided must have an accessible no-argument (or default) constructor. Such as:

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, one where clause is used for each type parameter
Such as:

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 the type parameters of a generic method, such as:

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

Note that the syntax for describing type parameter constraints is one for both the delegate and the method:

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


Related articles: