Part 05 of a hands-on C# practice series. Five runnable, heavily commented examples: why generics exist (with a live ArrayList crash), constraints as compile-time contracts, variance (in/out) — the guaranteed interview topic — demonstrated with running code including broken array covariance, generic math (INumber<T>, .NET 7), and the practical shapes you'll write at work (Result<T>, generic repository, the per-type statics gotcha).
dotnet run # all examples
dotnet run 3 # just one (e.g. variance)| # | Topic | Highlights |
|---|---|---|
| 01 | Why generics | ArrayList runtime crash vs compile-time safety, open vs closed types |
| 02 | Constraints | where T : interface/new()/struct, generic Max, default(T) |
| 03 | Variance | out=covariant, in=contravariant, why List<T> is invariant, array covariance is broken |
| 04 | Generic math | one Sum<T> for int/double/decimal, T.Zero, IParsable<T> |
| 05 | Practical | Result<T> with Map, Repository<T> (DbSet's idea), per-type statics |
- out = produces = covariant (same direction); in = consumes = contravariant (flipped).
- A constraint puts the requirement in the signature — casts hide it until runtime.
- Statics in a generic type exist once per closed type (
Counter<int>≠Counter<string>).
← Previous: 04 Async/await · Next: 06 Types & memory →
| Part | Topic |
|---|---|
| 01 | Collections |
| 02 | LINQ |
| 03 | Delegates & events |
| 04 | Async/await |
| 05 | Generics (this repo) |
| 06 | Types & memory |
| 07 | Exceptions |
| 08 | Modern C# 8–12 |
| 09 | Strings & text |
| 10 | Files & JSON |
| 11 | MiniShop microservices (finale) |
Matej Zlatunić
Released under the MIT License. Feel free to use it for learning.