C# Generics and When We Use Them

shoupn profile image Nick Shoup ・4 min read

This post was originally published on my blog Fundamentals of Code

Generics in C Sharp

I wanted to give some demonstrations around the use of Generics in the C# language. Generics are a very valuable tool and have a few benefits to their use, one of which is Type Safety in our classes. If you have been using C# for a while, you will most likely have used List<T> which implements from numerous interfaces that are part of the System.Collections.Generics namespace. [You can read about C# List's on Microsoft's docs][1]. You'll notice that when initializing new List in C# you must use a special bit of syntax, which looks like this var stringList = new List<string>();. You must initialize a List<T> in the following way.

A generic list must have a placeholder for the type it uses, in our example, the placeholder is of data type string. This offers an advantage over your traditional ArrayListcollections in C#. The advantage is namely because of type safety, but there is also in many cases the benefit of increased performance and code reuse. If you attempt to add something to a generic list that was initialized with a specific type but then attempt to add something of a different data type you will get a compilation error similar to the following - Argument 1: cannot convert from 'int' to 'string', this is not the case with an ArrayList, where you can add an assortment of data types.

var stringList = new List<string>();
stringList.Add(10);//Argument 1: cannot convert from 'int' to 'string'

The above example is a commonly used implementation of how we can use Generics, but what are some other ways, that we can use Generics? Let's take a look at some different examples.


Often times we will use Generics in our method signatures, this will help to enforce values being passed in as well as increase the level of type-safety. Let's look at the below code snippet.

public T Add<T> (T num1, T num2)
   dynamic a = num1;
   dynamic b = num2;
   return a + b;

The above code may not be useful on its surface however if you are using a method where type-safety and enforcement become necessary, this is a way to do so, while also maintaining code reuse. For example, the above could be used if you wanted to perform a math operation on a float in one implementation, a double in another or an integer. Usually, though the actual use of Generics is applied to the class itself and then applied to the class properties, methods, etc.

Classes and Generics

This way we can create a type-safe class. Hopefully, you can see how the use of generics allows for the reuse of code.

//This is how you declare a class signature which uses a Generic Type
public class GenericList<Type>
        public void Add(Type input) 
            //logic for adding to list..


public class GenericFields<Type>
    private Type _value;

    public GenericFields(Type value)
        this._value = value;

    // using properties 
    public Type value 
        // using accessors 
            return this._value; 
            this._value = value; 


The first example of our GenericsList class shows an ad-hoc implementation for a method that has the must implement the type that is passed in when declaring our class. For example, the implementation would look like this in code when using our class.

GenericList<object> objectList = new GenericList<object>();
object myObject = new object();

Hopefully, this helps make sense how the use of List from using System.Collections.Generic; works in C#. The class placeholder enforces the later used type. So if we were to then create another instance of our class it would look like the following:

GenericList<string> stringList = new GenericList<string>();
string myString = "FooBaz string";

Now for the implementation of our GenericFields class let's look at the actual implementation.

GenericFields<string> genricString = new GenericFields<string>("test string");
Console.WriteLine(genricString.value);//test string
genricString.value = "new string value";
Console.WriteLine(genricString.value);//new string value

//The below code will throw the following compilation error. 
genricString.value = 10;//cannot implicitly convert type 'int' to 'string'

Advantages of Generics

  • Reusability: You can use a single generic type definition for multiple purposes in the same code without any method overriding or code modification. For example, you can create a generic method to perform a math operation. You could then use the method to perform the same operation on double float, or int.

  • Type Safety: Generic data types provide better type safety, especially in the case of collections, which is where you will most likely be using them the most from the System.Collections.Generics namespace.

  • Performance: Generic types provide better performance because they reduce the need for boxing, unboxing, just read this stackoverflow post for more information about this subject.

Posted on by:

shoupn profile

Nick Shoup


GIS Developer, outdoor enthusiast, cryptocurrency/blockchain enthusiast, father, and husband. I really just want to share my passion for coding with others.


markdown guide

Please don't dynamic as a part of a generic method. The Add method in your post would throw a runtime exception as soon as you try to call it with a type that doesn't support the + operator - which is basically most types.

The point of Generics is to a allow you to write code that can be reused for multiple types, but to do that properly you have to either write code that doesn't involve the types themselves (like a List<T>, where the generic class only acts as the collection of T) or use generic constraints, that will allow your method/class/property to interact with the T in a truly type safe way.


Great intro Nick. You have a nice writing style. And there ar so many places you could go with a follow-up, too... constraints, interfaces, more info on boxing.


Thanks Tom! I truly appreciate the feedback. I will be doing additional posts on C# and will either update this post to include constraints as it seems to fit the best here, but was going to do a separate post on boxing/unboxing. Interfaces are also going to be part of separate post.


Yep, I was looking for constraints in the article too. I think they go hand in hand with generics.


I agree about then going hand in hand. I'm most likely going to update this post to include it.