Demystifying C# Generics

AramT
1,417 views

Open Source Your Knowledge, Become a Contributor

Technology knowledge has to be shared and made accessible for free. Join the movement.

Create Content

Constraints are like rules or instructions to define how to interact with a generic class or method. They can restrict the parameter that will be replaced with T to some certain type or class or have some properties, like to be new instance of class.

If the consumer of the generic method or class didn’t comply with the constraint set on the parameter T, it will result in a compilation error.

With constraints you can for example, specify a generic parameter to only accept reference types (class), or value types (struct), or to be a class that implements an interface.

Constraints can be defined using the keyword where

Reference Constraint

Let’s see the below example that includes having a constraint on the above Lesson class, we will put a constraint that the parameter T should only be of a reference type, value types are not allowed. so it will be defined as where T: class

The below code shows how you can create a generic class with a constraint that the argument provided as T must be a reference type, run it to see test results
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
·namespace GenericsLesson
{
class LessonWithConstraint<T> where T: class
{
private T t;
public void Set(T t){
this.t = t;
}
public T Get()
{
return t;
}
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Now if you try to intialize the above Lesson class using a non-reference type as its parameter, like int , you will get a compilation error:

The type ‘int’ must be a reference type in order to use it as parameter ‘T’ in the generic type or method ‘Lesson’

You can only call it with a reference type, like string or any class.

Custom Constraint

You can define constraint that a parameter must be implementing some interface. Let’s take this example:

Here you have a class Container, that defines a generic parameter T, with a constraint that anyone wants to use this class, must pass an argument that implements the IItem Interface.

So here we added the IItem Interface, that has a method showName().

We also added a class Item, that will implement IItem Interface.

Now in the caller part, what will happen is that we will initialize Item object, and then initialize Container while providing it and Item Type, and then calling the set method of container to set the item that was initialized.

The below code shows you how you can create a generic class that its parameter must implement an interface
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
·namespace GenericsLesson
{
class Container<T> where T: IItem
{
private T t;
public void Set(T t)
{
this.t = t;
}
public T Get()
{
return t;
}
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Open Source Your Knowledge: become a Contributor and help others learn. Create New Content