Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The sizeof operator returns an int representing the unmanaged memory size, in bytes, of a specified type. This value includes any padding added by the compiler for memory alignment, but it does not reflect managed heap object overhead or stack alignment applied dynamically by the Common Language Runtime (CLR).
int size = sizeof(type);

Safe Context Evaluation

Since C# 7.3, the sizeof operator can be used without an unsafe context for any unmanaged type. The evaluation behavior depends on the specific type: Compile-Time Constants For built-in simple types, the compiler replaces the sizeof expression with a constant integer value during compilation. This result can be assigned to a const variable. This applies to:
  • Built-in Simple Types: sbyte (1), byte (1), short (2), ushort (2), int (4), uint (4), long (8), ulong (8), float (4), double (8), char (2), bool (1), decimal (16).
  • Enums: Evaluates to the size of the enum’s underlying type.
const int intSize = sizeof(int);         // Evaluates to 4 at compile-time
const int decimalSize = sizeof(decimal); // Evaluates to 16 at compile-time
Runtime Evaluation For custom unmanaged structs and unmanaged generic type parameters, the sizeof expression does not yield a compile-time constant. Instead, the C# compiler emits the sizeof IL instruction, which is evaluated by the JIT compiler at runtime (or during AOT compilation). Because it is not a constant expression, the result cannot be assigned to a const variable. The returned size accounts for field sizes plus any structural padding required for alignment.
public struct CustomPoint
{
    public byte X;  // 1 byte
    public int Y;   // 4 bytes
}

// Valid in safe code, but NOT a compile-time constant. 
// Evaluates to 8 at runtime due to 3 bytes of padding added after 'X'.
int structSize = sizeof(CustomPoint); 

int GetSize<T>() where T : unmanaged
{
    return sizeof(T); // Evaluated at runtime via IL instruction
}

Unsafe Context Evaluation

Evaluating the size of pointer types requires an unsafe context and requires compiling the project with the AllowUnsafeBlocks flag enabled. The size of a pointer depends on the architecture of the executing process.
unsafe
{
    // Evaluates to 8 on a 64-bit architecture, 4 on a 32-bit architecture
    int pointerSize = sizeof(int*);       
}

Technical Constraints

  • Reference Types: sizeof cannot be applied to reference types (e.g., class, string, object, arrays). The CLR manages the memory layout of reference types dynamically, making their unmanaged size indeterminate.
  • Managed Structs: sizeof cannot be applied to structs that contain reference type fields, as they do not satisfy the unmanaged constraint.
  • Unconstrained Generics: sizeof cannot be applied to a generic type parameter unless the unmanaged constraint is explicitly applied.
Master C# with Deep Grasping Methodology!Learn More