All writing
5 min read

Understanding Generics in C#

Generics let you write code once and use it with any type — more reusable, more concise, and safer than casting everything through object.

C#.NETBackend

Generics let you write code that works with any data type while staying fully type-safe. Instead of duplicating a method per type — or casting everything through object and hoping — you write it once with a type parameter. You declare that parameter with angle brackets: <T>.

A generic method

Here is a method that prints a value of any type:

csharp
public static void Print<T>(T value)
{
    Console.WriteLine(value);
}

It works with anything you hand it:

csharp
Print(10);              // 10
Print("Hello, world!"); // Hello, world!

Generic classes

The same idea scales up to whole classes. A generic class declares its type parameter after the class name — and T is just a convention; any name works.

csharp
public class Box<T>
{
    private T item;
    public void Put(T value) => item = value;
    public T Get() => item;
}

Why bother

Reusability — one implementation serves every type. Conciseness — less duplicated code. Performance — no boxing or casting when you work with value types. Safety — the compiler enforces the right type, so a whole class of runtime errors simply cannot happen.

You already use them

Most of the .NET collections are generic: List<T> (a resizable list), Dictionary<TKey, TValue> (name/value pairs), Queue<T> (FIFO), Stack<T> (LIFO), and Comparer<T>. Every time you write List<string>, you are using generics.

Generics are one of C#'s most important features. Whether in a method or a class, they are how you write code that is flexible and reusable without giving up the compiler's safety net.


Written by Fady Ehab Amer

Get in touch →

Keep reading