Generics are a new feature in version 2.0 of the C# language and the common language runtime (CLR). Generics introduce to the .NET Framework the concept of type parameters, which 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.
by MSDN
There are many algorithms which are not data type dependent. To design such algorithms we can omit the actual data type in design time with type parameter. When the client code use that algorithm then they pass the actual data type for execution.
// 'T' is the type parameter. public class List<T> : // Implemented interfaces goes here... { // Members goes here... } // Client code replace 'T' with actual types. List<string> empNames = new List<string>(); List<int> empAges = new List<int>();
Another alternative is to use a System.Object type. Because System.Object class is the base class for all in .NET Framework, the client code can pass any type in that algorithm.
ArrayList empAges = new ArrayList(); // Boxing. employeeNames.Add(30); employeeNames.Add(35); employeeNames.Add(45); // Unboxing. int result = (int)employeeNames[1];
But doing so we can loose type safety. Here the compiler do not know the actual type which is store inside the System.Object type. So if type is not compatible then the exception will be thrown at runtime. Another disadvantage is performance. When we store a value type inside this collection then boxing will performed and at the time of retrieving unboxing will perform. Boxing and unboxing is a expensive procedure.
// Runtime exception. string result = (string)empAges[1];
If we use Generic then our code will be type safe. Also there is no use of boing and unboxing which hurts the performance.
List<int> empAges = new List<int>(); // Not boxing. employeeNames.Add(30); employeeNames.Add(35); employeeNames.Add(45); // Not unboxing. int result = empAges[1];
If we accidentally try to store the value is some other data type then the compiler reports an error. That means the compiler know the actual type here.
// Can not compile because compiler know the actual // data type is 'int'. string anotherResult = empAges[1];
This is way it is recommended to use Generic collection classes when possible. But if we want to store different data type value in same collection which is rare then we have to use the collection classes which uses System.Object type.