Phase 9 of 30 · Topic 9.2

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.