C# Generics

In this article, you will learn about C# generics.

What are Generics?

 
It’s kind of difficult to explain what ‘Generics’ are but if you have used a list before in your coding, you unknowingly know ‘Generics’.
 

Prerequisites

 
You should at least know ‘List’ Data Structures in C# and how to use them.
 
Usually, developers create a C# list in the following manner.
 
C# Generics
 
The red square box indicates generics. It restricts the addition of only ‘Integer’ items in the list.
 

Why Generics?

 
Before ‘Generics’ was introduced in C#, List was used in the following manner.
  1. ArrayList arrayList = new ArrayList();  
  2.             arrayList.Add(0);  
  3.             arrayList.Add(10);  
  4.             arrayList.Add("Sam");  
  5.             arrayList.Add(30);  
  6.             arrayList.Add("Jacob");  
The problem with the above code is that you can add any ‘Type’ in list (Observe how ‘string’ and ‘integer’ are added to the list.)
 
If you do so, it will be a problem at the time of retrieval because if you try to fetch items at the index, it will return ‘object’ and you can’t do much with it.
 
The solution is to ‘Cast’ the retrieved ‘object’ to the required type as follows.
  1. var v = (int)arrayList[1];  
But in real life, lists are made up of thousands of elements. It’s inconvenient to verify each element and then cast it. In case casting is not possible, the program will throw an exception. Please see the following image.
 
C# Generics
 
You can see we are trying to cast ‘string’ to ‘int’ which is not possible, hence the code throws an exception.
 
To overcome this problem, ‘Generics’ were introduced.
 

When to use Generics?

 
Anytime you create a list, you are utilizing ‘Generics’; not creating them or using them.
  1. private List<int> intList = new List<int>();  
So, the question comes when to use ‘Generics’ and when to not.
 
Any time in your code you want the logic to be applicable to ‘All Types’, you can use ‘Generics’.
 

Explanation

 
Let’s assume that developers of the ‘List’ Data Structure for ‘Integers’ wrote the following code.
  1. class MyListInteger  
  2. {  
  3.     private List<int> intList = new List<int>();  
  4.   
  5.     public void Add(int number)  
  6.     {  
  7.         intList.Add(number);  
  8.     }  
  9.   
  10.     public int GetItem(int index)  
  11.     {  
  12.         return intList[index];  
  13.     }  
  14. }  
Let’s assume they want to create the ‘List’ data structure for ‘string’ as well. They will have to repeat the code for ‘string’ as below.
  1. class MyListString  
  2. {  
  3.     private List<string> stringList = new List<string>();  
  4.   
  5.     public void Add(string item)  
  6.     {  
  7.         stringList.Add(item);  
  8.     }  
  9.   
  10.     public string GetItem(int index)  
  11.     {  
  12.         return stringList[index];  
  13.     }  
  14. }  
Imagine if they have to repeat the code for every type, which is chaos.
 
‘Generics’ to the rescue.
 
You can create ‘Generics’ class for the above scenario as mentioned in the below code.
  1. class MyList<T>  
  2. {  
  3.     private List<T> genericList = new List<T>();  
  4.   
  5.     public void Add(T item)  
  6.     {  
  7.         genericList.Add(item);  
  8.     }  
  9.   
  10.     public T GetItem(int index)  
  11.     {  
  12.         return genericList[index];  
  13.     }  
  14. }  
Where ‘T’ is called a placeholder or ‘Type parameter’. ‘T’ is usually  referred to as ‘Type’.
 
When you create an object of the above class, all the ‘T’s are replaced by ‘Type’ that is used to create an object.
  1. MyList<int> ml = new MyList<int>();  
After the above line, all ‘T’s are replaced by ‘int’.
 
The class will look like below after the above initialization (Imaginary).
  1. class MyList  
  2.    {  
  3.        private List<int> intList = new List<int>();  
  4.   
  5.        public void Add(int number)  
  6.        {  
  7.            intList.Add(number);  
  8.        }  
  9.   
  10.        public int GetItem(int index)  
  11.        {  
  12.            return intList[index];  
  13.        }  
  14.    }