Generics are another feature of the .NET Framework Common Language Runtime (CLR). It was introduced in .NET Framework 2.0 and has been around ever since. The basic principle is the re-use of code. As a developer, you often find yourself with a collection of data (collection of objects) on which you need to perform an action (search, sort, insert at a certain position, comparing,…). What makes generics so useful is that none of these algorithms are defined to a type. It is up to you to define this type. After you’ve defined the type, every action performed on the collection will use that type, so it’s type safe. Everything concerning generics is comprised in the System.Collections.Generic namespace. Often used types are List<T>, Dictionary<TKey,TValue>, LinkedList<T>,… The ‘T’ of course stands for the type argument.
Meaning if you want to create a list of strings, you can define one, and use the Add()-method to fill your collection. Do note that here again type safety comes into play. Since you have defined your collection as a collection of strings, the parameter you can assign to the Add()-method will have to be of type string. You can see this when looking at the list of methods that are implemented on List<T>.
1: List<string> listOfStrings = new List<string>();
2:
3: listOfStrings.Add("This is the first string");
4: listOfStrings.Add("second string");
5: listOfStrings.Add("third");
6:
7: foreach (string s in listOfStrings)
8: {
9: Console.WriteLine(s);
10: }
Running the application will give the following output:

As Jeffrey Richter mentions in his book CLR via C#, the most important benefits of generics are source code protection, type safety, cleaner code and better performance. I’ve already mentioned the topic of type safety earlier. “Source code protection” means that the developer that uses the code, doesn’t has to have access to it. In our case of a List<T>, that means that you can call the Sort()-method, but the source code is hidden from you. Cleaner code is a result of type safety, since you don’t have to cast from one type to another all the time. The better performance benefit is actually a logical consequence of re-using code and code protection.
Many algorithms for sorting, searching,… have been implemented thousands of times over the years. And instead of constantly re-inventing these algorithms, one good, re-usable implementation will do. This is what generics provides us. Now of course, you need to tweak these algorithms so they will work for you. As long as you are working with primitives (as in the example above), there won’t be a problem. But if you are working with classes of your own, you will have to do your own implementation of the Equals() and GetHashcode() method. If you don’t have your own implementation of these methods, the default methods (provided by System.Object) will be used. As mentioned in previous posts the Equals()-method’s default implementation compares reference addresses. Microsoft, on its part, has done a great effort to implement generics. They had to create new IL (Intermediate Language) instructions and reflection members, modify metadata tables, modify the language implementations to support the new syntax, modify compilers,…