Comprehensive Generic Constraints (`where T : ...`)
1Concept
Generic constraints enforce compile-time safety and unlock operations on generic type parameters. Options include `class`, `struct`, `notnull`, `unmanaged`, `new()`, and base class/interface bounds.
2Architecture Diagram
Generic Constraint Matrix: ├── where T : struct ──> Must be a non-nullable value type ├── where T : unmanaged ──> Must be a struct with NO reference type fields (Blittable) ├── where T : notnull ──> Non-nullable value or reference type ├── where T : new() ──> Must have a public parameterless constructor └── where T : BaseClass, IFoo ──> Type hierarchy enforcement
3Code Example
C# 13 & .NET 9
using System;
public class FactoryRegistry
{
// Enforces unmanaged blittable struct
public static unsafe int GetByteSize<T>() where T : unmanaged
{
return sizeof(T);
}
// Enforces parameterless constructor
public static T CreateInstance<T>() where T : class, new()
{
return new T();
}
}
public struct Matrix2x2 { public int A, B, C, D; }
public class GenericConstraintsDemo
{
public static void Main()
{
int size = FactoryRegistry.GetByteSize<Matrix2x2>();
Console.WriteLine($"Blittable Struct Size: {size} bytes");
}
}4Expected Output
Blittable Struct Size: 16 bytes
5Key Takeaways
- ✓`where T : unmanaged` allows direct pointer math and interop buffer pinning.
- ✓`where T : allows ref struct` (C# 13) allows generic types to accept `Span<T>`.
- ✓Constraints eliminate runtime reflection checks.