Generics in .Net

Introduction

 
Generics (in the "System.Colloections.Generic" namespace) was introduced in a previous version of .Net (actually the Common Language Infrastructure (CLI)). It's not a new concept; it's available in C++ in the form of templates.
 
It is an important feature of .Net programming, allowing a class and methods such as lists, hash table, and queue and so on to be defined with a type T as a parameter.
 
The type of generic parameter is specified only at the time of declaration. With the help of this, the programmer will improve the performance of an application and type-safety.
 
A Generic class encapsulates operations that do not have a specific data type.
Generics are also known as Parametric polymorphism.
 
Example
 
You can write a single class MyList<T> and you can use the code as MyList<int>,  MyList < string > or MyList<MyClass>. Without any casting or boxing operation.
 
Advantages of using generic
 
An ArrayList is a highly convenient collection class that can be used without modification to store any reference or value type. 
 
Generics provide a solution for the limitation of an Arraylist collection in the Common Language Runtime.
 
We will see the limitations of non-generic collection classes, using the ArrayList collection class.
  1. using System;  
  2. using System.Collections;  
  3.    
  4. public class ArrayList  
  5. {  
  6.     static void ArrayList()  
  7.     {  
  8.    
  9.         // Creates and initializes a new ArrayList.  
  10.         ArrayList List1 = new ArrayList();  
  11.         List1.Add("Hello");  
  12.         List1.Add("World");  
  13.    
  14.         // Creates and initializes a new ArrayList.  
  15.         ArrayList List2 = new ArrayList();  
  16.         List2.Add(1);  
  17.         List2.Add(2);  
  18.     }  

In the ArrayList Collection, any reference or value type data added to an ArrayList must be typecast to "System.Object". If the items are value types then they must be boxed when they are added to the list and unboxed when they are retrieved. The casting, boxing, unboxing operation reduce the performance.
 
In a generic List<T> collection, using the "System.Collections.Generic" namespace,
 
we will see the same operation.
  1. using System;  
  2. using System.Collections.Generic;  
  3. public class TArrayList  
  4. {  
  5.     public static void ArrayList()  
  6.     {  
  7.         List<int> List1 = new List<int>();  
  8.         // No boxing, no casting:  
  9.         List1.Add(3);  
  10.     }  

As compared to Arraylist it would be safer and faster.
  • Code Reusability in generics  (Advantage)
Generics provide type-safe code with reusability.  
 
Example
 
Suppose you need to sort the integer and floating type numbers, let's see how to do it in collections and generics.
 
The following shows how to do it in a collection:
  1. using System.Collections;  
  2.    
  3. public class GenerciArrayList  
  4. {  
  5.     public static void Sort()  
  6.     {  
  7.         int[] intArray = { 8, 10, 2, 6, 3 };  
  8.    
  9.         // Sort your int array  
  10.         Array.Sort(intArray);  
  11.         foreach (var i in intArray)  
  12.         {  
  13.             Console.WriteLine(i);  
  14.         }  
  15.         // Sort it the other way  
  16.    
  17.         string[] strArray = { "A""D""C""E""B" };  
  18.         Array.Sort(strArray);  
  19.    
  20.         foreach (var i in strArray)  
  21.         {  
  22.             Console.WriteLine(i);  
  23.         }  
  24.         Console.ReadLine();  
  25.     }  

The following shows how to do it using Generics:
  1. using System.Collections.Generic;  
  2.    
  3. public class ArrayList  
  4. {  
  5.     private static object[] Sort<T1>(object[] iInputeArray)  
  6.     {  
  7.         Array.Sort(iInputeArray);  
  8.         return iInputeArray;  
  9.     }  

Here T is a type. Once we can create this method, we can call it with various data types as follows.
 
In this way, a Generic provides code re-usability.
  1. public  static void SortList()  
  2. {  
  3.      object[] iInputArray = { 3, 5, 8, 6, 10, 6, 2, 1, 12 };  
  4.      iInputArray = Sort<int>(iInputArray);  
  5.   
  6.     foreach (Object obj in iInputArray)  
  7.     Console.Write("   {0}", obj);  
  8.   
  9.    object[]strInputArray = { "A" ,"C""T""R""E""D"  };  
  10.    strInputArray = Sort<int>(strInputArray);  
  11.   
  12.    foreach (Object obj in strInputArray)  
  13.    Console.Write("   {0}", obj);  
  14.   
  15.    Console.WriteLine();  
  16.    Console.ReadLine();  
  17. }
Benefits
 
The following are the benefits of generics:
  • There is no need for casting for accessing the elements of data.
  • Code is not duplicated for multiple types of data.
  • Generic can hold the data with the same type and we can decide what type of data that collection hold.
  • You can create your own generic interface, classes, method, events, and delegate.
Why use Generics?
 
There are mainly two reasons to use generics as in the following:
  1. Performance: Collections that store the objects use boxing and unboxing on data types. A collection can reduce performance.
    By using generics it helps to improve the performance and type safety.
  2. Type Safety: there is no strong type information at compile time as to what is stored in the collection.
When to use Generics
  • When you use various undefined data types, you need to create a generic type.
  • It is easier to write code once and reuse it for multiple types.
  •  If you are working on a value type then for that boxing and unboxing operation will occur, Generics will eliminate the boxing and unboxing operations.
Boxing: Conversion of a value type into a reference type of variable. When the variable of a value type is to be converted to a reference type, the object box is allocated to hold the value and copies the value into a box.
 
Unboxing: It is just the opposite of boxing.   
 
Example Boxing/Unboxing
  1. class BoxUnbox  
  2. {  
  3.   Static void Main ()  
  4.   {  
  5.      Int i=1;  
  6.      Object o=i;    //boxing  
  7.      Int j = (int) o; //unboxing  
  8.   }  
  9. }            
Generic Class
 
The common use of a generic class is with collections like a linked list, hash table, stack, queue, and tree. The addition and removal of an item from a collection are basically the same.
 
Example  
  1. using System.Collections.Generic;  
  2. namespace Generic  
  3. {  
  4.     public class ArrayClass<T>  
  5.     {  
  6.         object Store;  
  7.         public void Push(object Obj)  
  8.         {  
  9.             Store = Obj;  
  10.         }  
  11.         public object Pop()  
  12.         {  
  13.             return Store;  
  14.         }  
  15.     }  

Here T is a type of parameter.  We can pass any data type as a parameter.
 
This class can be used as below.
  1. public class SubClass  
  2. {  
  3.     public static void MyClass()  
  4.     {  
  5.         ArrayClass<int> intArray = new ArrayClass<int>();  
  6.         intArray.Push(10);  
  7.         object intReturnValue = intArray.Pop();  
  8.         Console.Write("   {0}", intReturnValue);  
  9.    
  10.         ArrayClass<string> strArray = new ArrayClass<string>();  
  11.         strArray.Push("Hello word");  
  12.         object strReturnValue = strArray.Pop();  
  13.         Console.Write("   {0}", strReturnValue);  
  14.         Console.ReadLine();  
  15.     }  

Generic Methods
 
Generic methods are the method yet declared with type parameters.
 
Examples
  1. using System.Collections.Generic;  
  2.    
  3. public class ArrayList  
  4. {  
  5.     static void Swap<T>(ref T lhs, ref T rhs)  
  6.     {  
  7.         T temp;  
  8.         temp = lhs;  
  9.         lhs = rhs;  
  10.         rhs = temp;  
  11.     }  

The following method shows how to call the method above.
  1. public static void TestSwap()  
  2. {  
  3.     int a = 1;  
  4.     int b = 2;  
  5.     Swap<int>(ref a, ref b);  
  6.     System.Console.WriteLine(a + " " + b);  
  7.     Console.ReadLine();  

Conclusion

 
We used a generic type provided by the .Net Framework. These include the dictionary and list. But you can provide your own type.