LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 3318 min read

Generics

Learn how to write type-safe, reusable classes and methods using C# generics.

The Problem Generics Solve

Without generics, you'd need a separate method or class for every type you want to support (`PrintInt`, `PrintString`, `PrintBool`...). Generics let you write one implementation that works with any type, safely.

You've Already Used Generics

List<T> and Dictionary<TKey, TValue> from the previous lesson are themselves generic types — the <T> syntax lets them work with any type you plug in.

Generic Methods

static void Print<T>(T value)
{
Console.WriteLine($"Value: {value}");
}
Print(42); // T is int
Print("hello"); // T is string
Print(3.14); // T is double

Generic Classes

class Box<T>
{
private T content;
public void Store(T item) => content = item;
public T Retrieve() => content;
}
var intBox = new Box<int>();
intBox.Store(42);
Console.WriteLine(intBox.Retrieve());
var stringBox = new Box<string>();
stringBox.Store("Hello");
Console.WriteLine(stringBox.Retrieve());
Output

Click Run to see what this code prints.

Type Constraints

You can restrict which types are allowed with the `where` clause — useful when your generic code needs to call specific members on the type.

static T Max<T>(T a, T b) where T : IComparable<T>
{
return a.CompareTo(b) > 0 ? a : b;
}
Console.WriteLine(Max(5, 10)); // 10
Console.WriteLine(Max("apple", "banana")); // banana

FAQs

No — the CLR specializes generic code for value types at compile/JIT time, so there's effectively no performance penalty.

Summary

  • Generics let you write one implementation that works across many types safely.
  • List<T> and Dictionary<TKey,TValue> are built-in generic types.
  • Type constraints (`where`) restrict which types are allowed and what you can do with them.
Next Lesson →

Delegates