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 intPrint("hello"); // T is stringPrint(3.14); // T is doubleGeneric 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)); // 10Console.WriteLine(Max("apple", "banana")); // bananaFAQs
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.