Phase 9 of 30 · Topic 9.1

CLR Generic Specialization: Value Types vs Reference Types

1Concept

When a generic `List<T>` is instantiated with a value type (`int`), RyuJIT compiles dedicated native machine code for that exact struct size. For reference types (`string`, `object`), all instances share a single unified canonical machine code implementation.

2Architecture Diagram

Generic Type `Processor<T>`:
├── Processor<int>    ──> JIT emits specialized 4-byte native machine code
├── Processor<double> ──> JIT emits specialized 8-byte SSE machine code
└── Processor<string> ──> JIT emits canonical shared pointer code (Canon)
    └── Processor<User> ── shares same code as Processor<string> (Saves RAM!)

3Code Example

C# 13 & .NET 9
using System;

public class CacheStore<T>
{
    private T _data;
    public CacheStore(T data) => _data = data;
    public T Value => _data;
}

public class GenericSpecializationDemo
{
    public static void Main()
    {
        var intCache = new CacheStore<int>(42);       // JIT specialized for int
        var strCache = new CacheStore<string>("DOTNET"); // JIT Canon pointer shared

        Console.WriteLine($"Int Value: {intCache.Value}");
        Console.WriteLine($"String Value: {strCache.Value}");
    }
}

4Expected Output

Int Value: 42
String Value: DOTNET

5Key Takeaways

  • Value type generics incur zero boxing and run at raw native C speed.
  • Reference type generics share machine code, preventing code bloat in memory.
  • Static fields in generic classes are unique per closed generic type (`MyClass<int>.Count != MyClass<string>.Count`).