Home / Forums / C-Style Unions in C# using StructLayout(LayoutKind.Explicit) and FieldOffset

UnreliableCode Community

Developer Research, Reverse Engineering & Coding Community

Source

C-Style Unions in C# using StructLayout(LayoutKind.Explicit) and FieldOffset

StructAligner
Data-Oriented Design
VIP
Rep: 301
Join Date: Dec 2025
Posts: 8
Thanks: 25
2y ago · Jun 28, 2024 2:25 PM
#1
In C/C++, unions allow multiple variables to share the exact same memory location. In C#, you can achieve the exact same behavior using
CODE
[StructLayout(LayoutKind.Explicit)]
!

Example: Fast 32-bit Color Converter Union
CSHARP
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Explicit)]
public struct Color32Union
{
    // Raw 32-bit unsigned integer (ARGB)
    [FieldOffset(0)] public uint RawValue;

    // Individual 8-bit color channels sharing the same 4 bytes!
    [FieldOffset(0)] public byte B;
    [FieldOffset(1)] public byte G;
    [FieldOffset(2)] public byte R;
    [FieldOffset(3)] public byte A;
}

// Usage:
Color32Union col = default;
col.RawValue = 0xFF1084FF; // Set as 32-bit hex

Console.WriteLine($"R: {col.R}, G: {col.G}, B: {col.B}, A: {col.A}");
// Modifying blue channel updates the raw uint instantly with zero bit shifts!
col.B = 0x00;
StructAligner · Data-Oriented Design
Structure of Arrays (SoA) vs Array of Structures (AoS) for m...
The following users thanked StructAligner for this post:
NativeCoder
Low-Level C++ / ASM
VIP
Rep: 374
Join Date: Jun 2025
Posts: 12
Thanks: 20
2y ago · Jun 28, 2024 6:53 PM
#2
Explicit field offsets are also great for IEEE 754 float-to-int bitcasting without calling
CODE
BitConverter.SingleToInt32Bits()
on older .NET frameworks.
NativeCoder · Low-Level C++ / ASM
Passionate about cache locality, SIMD instructions, and raw ...
BytePusher
Memory & Performance
MEMBER
Rep: 209
Join Date: Dec 2025
Posts: 13
Thanks: 32
2y ago · Jun 28, 2024 10:53 PM
#3
Just be careful with overlapping managed references (like object pointers) with primitive value types—the CLR TypeLoader will throw a
CODE
TypeLoadException
for safety if managed pointers overlap with raw integers!
BytePusher · Memory & Performance
Zero-allocation C# code using Span<T>, Memory<T>, and Unsafe...