What are generics in C# and what problems do they solve?
Learn what generics are in C#, how type parameters and constraints work, and how they deliver type safety, code reuse, and no boxing of value types.
Expected Interview Answer
Generics let you write classes, interfaces, and methods with type parameters (like List<T>) so the same code works with any type while staying strongly typed, eliminating casting and boxing and catching type errors at compile time.
Before generics, reusable collections used object, forcing casts and boxing of value types and pushing type errors to runtime. Generics parameterize the type, so List<int> stores ints directly with no boxing and List<string> is type-checked by the compiler. Constraints (where T : ...) let you require an interface, base class, reference/value type, or a public parameterless constructor, giving safe access to members. The CLR specializes generics for value types and shares one instantiation for reference types, so you get reuse without a runtime performance penalty.
- Compile-time type safety instead of runtime cast errors
- No boxing/unboxing of value types
- Code reuse across many types without duplication
- Cleaner APIs with no casting
- Constraints give safe access to type members
AI Mentor Explanation
Generics are like a kit bag designed to hold any equipment yet stamped for exactly one kind at a time. A bag labelled for bats only ever holds bats, so you never reach in expecting a bat and pull out a ball. Without generics you had one unlabelled bag holding everything, forcing you to inspect and re-check each item, risking grabbing the wrong gear mid-match.
Step-by-Step Explanation
Step 1
Identify repeated code
Notice logic duplicated per type or a collection using object with casts everywhere.
Step 2
Introduce a type parameter
Add <T> to the class, interface, or method so the type becomes a parameter.
Step 3
Use T in the signature
Replace concrete types with T in fields, parameters, and return types.
Step 4
Add constraints if needed
Use where T : IComparable<T>, class, struct, or new() to access required members safely.
Step 5
Instantiate with a concrete type
Create List<int> or Repository<User>; the compiler enforces type safety.
Step 6
Benefit at runtime
Value types avoid boxing and the CLR specializes them, so reuse costs no performance.
What Interviewer Expects
- Type safety and elimination of casts
- Avoiding boxing/unboxing of value types
- Understanding of generic constraints (where clauses)
- Code reuse without duplication
- Awareness of how the CLR handles generic types
Common Mistakes
- Confusing generics with the non-generic object approach
- Not using constraints and then being unable to call members on T
- Thinking generics are like C++ templates that duplicate all code
- Overlooking that value-type generics avoid boxing
- Using ArrayList instead of List<T> in new code
Best Answer (HR Friendly)
“Generics let you write one piece of code that works with many data types while the compiler still checks that you use it correctly. This means less duplicate code, fewer runtime errors, and better performance, which is why collections like List<T> are built with generics.”
Code Example
// Works for any type, but constrained to comparable types
public static T Max<T>(T a, T b) where T : IComparable<T>
{
return a.CompareTo(b) >= 0 ? a : b;
}
int bigger = Max(3, 7); // no boxing, T = int
string later = Max("apple", "pear"); // T = string, compile-time checked
// A generic class
public class Box<T>
{
public T Value { get; set; }
}
var intBox = new Box<int> { Value = 42 };Follow-up Questions
- What generic constraints does C# support?
- How do generics avoid boxing for value types?
- How do C# generics differ from C++ templates?
- What is covariance and contravariance in generics?
- Why prefer List<T> over ArrayList?
MCQ Practice
1. What key problem do generics solve compared to using object?
Generics give strong typing at compile time and store value types without boxing, unlike collections based on object.
2. Which keyword adds a constraint to a generic type parameter?
The where clause specifies constraints such as where T : IComparable<T>, class, struct, or new().
3. What does 'where T : new()' require?
The new() constraint requires that T has an accessible parameterless constructor so you can create instances of T.
Flash Cards
What are generics? — Types and methods parameterized by a type (like List<T>) that stay strongly typed while working with any type.
Two main problems generics solve? — Runtime cast errors (now compile-time safe) and boxing/unboxing of value types (now avoided).
What does a where clause do? — Constrains a type parameter, e.g. where T : class, struct, new(), or an interface/base class, enabling safe member access.
How does the CLR handle generics? — It specializes generics for each value type and shares one instantiation across reference types, so reuse has no perf penalty.