What is a constraint on generics in C#

By | August 25, 2018

Generics make it possible to design classes and methods that defer the specification of one or more types until the class or method is declared and instantiated by client code. For example, by using a generic type parameter T you can write a single class that other client code can use without incurring the cost or risk of runtime casts or boxing operations, as shown here:

class MyGenericClass<T>
{
private T genericMemberVariable;

public MyGenericClass(T value)
{
genericMemberVariable = value;
}

public T genericMethod(T genericParameter)
{
Console.WriteLine(“Parameter type: {0}, value: {1}”, typeof(T).ToString(),genericParameter);
Console.WriteLine(“Return type: {0}, value: {1}”, typeof(T).ToString(), genericMemberVariable);
return genericMemberVariable;
}

public T genericProperty { get; set; }
}

In the above example, the generic class MyGenericClass defines a placeholder for the type, but the placeholder is like a black box, because MyGenericClass doesn’t know anything about the placeholder type, whether it is primitive or non-primitive type, or an interface or custom class etc.

C# includes Constraints to specify which type of placeholder type with the generic class is allowed. It will give a compile time error if you try to instantiate a generic class using a placeholder type that is not allowed by a constraint. For example, if the generic constraints specify that only reference type can be used with the generic class then you cannot use value type to create an object of generic type.

Constraints can be applied using the where keyword. In the following example, MyGenericClass specifies the constraints that only a reference type can be used with MyGenericClass. This means that only a class can be a placeholder type not the primitive types, struct etc.

class MyGenericClass < T > where T: class
{
private T genericMemberVariable;

public MyGenericClass(T value)
{
genericMemberVariable = value;
}

public T genericMethod(T genericParameter)
{
Console.WriteLine(“Parameter type: {0}, value: {1}”, typeof(T).ToString(), genericParameter);
Console.WriteLine(“Return type: {0}, value: {1}”, typeof(T).ToString(), genericMemberVariable);
return genericMemberVariable;
}

public T genericProperty
{
get;
set;
}
}

So now, you cannot use int as a placeholder type. The following would give a compile time error.

MyGenericClass<int> intGenericClass = new MyGenericClass<int>(10);

String or any class type is a valid type because it is a reference type.

MyGenericClass<string> strGenericClass = new MyGenericClass<string>(“Hello World”); MyGenericClass<Student> strGenericClass = new MyGenericClass<Student>(new Student());

The following table lists the types of generic constraints.

Constraint Description
where T : class Type must be reference type.
where T: struct Type must be value type.
where T: new() Type must have public parameterless constructor.
where T: <base class name> Type must be or derive from the specified base class
where T: <interface name> Type must be or implement the specified interface.
where T: U Type supplied for T must be or derive from the argument supplied for U.

Multiple constraints:

A generic class can have multiple constraints as shown below.

class MyGenericClass<T, U> where T: class where U:struct{    …}

Constraint on Generic Methods

You can apply constraints on the generic methods also.

class MyGenericClass < T > where T: class
{
public T genericMethod < U > (T genericParameter, U anotherGenericType) where U: struct
{
Console.WriteLine(“Generic Parameter of type {0}, value {1}”, typeof(T).ToString(), genericParameter);
Console.WriteLine(“Return value of type {0}, value {1}”, typeof(T).ToString(), genericMemberVariable);
return genericMemberVariable;
}
}

Notes:

  1. Constraints specifies the kind of types allowed with the generics.
  2. Constraints can be applied using the where keyword.
  3. Six types of constraints can be applied: class, struct, new(), base class name, interface and derived type.
  4. Multiple constraints also can be applied.

 

Leave a Reply

Your email address will not be published. Required fields are marked *