C-style unions in .NET
ByteUnion – Unions in .NET/C#
Do you ever wonder what happened to the old-school C/C++ unions in C# ?
Unions were extremely usefull for a wide range of problems back in the days where we dared make bold assumptions about memory-layout and the width of variables.
.NET/C# does not allow us to make unions like that directly anymore, but we can still achieve most of the functionality by explicitly controlling the layout of classes and structs in C#
A tiny example
The System.Runtime.InteropServices namespace has the tools to handle the layout of structs and classes. It allows you to define fields in structures in a way so they even overlap.
This mechanism – when used with simple data types – can be used to simulate unions in C#.
Take a look at the following small class:
[StructLayout(LayoutKind.Explicit)] public class union { [FieldOffset(0)] public byte lowbyte; [FieldOffset(1)] public byte highbyte; [FieldOffset(0)] public ushort word; }
This is a very basic class containing only two bytes and a word. There are two very interesting things to note though.
- The whole class is given the “StructLayout(LayoutKind.Explicit)” attribute. This tells the compiler that we want to control the layout of the fields ourselves.
- Each field is then given an offset with the “FieldOffset” attribute. This is where the magic happens. The 16-bit word is placed so it overlaps the two 8-bit bytes.
Using it…
Now if you assign anything to the 16-bit word it will change the 2 bytes – and vice versa. The class can now be used like this:
union u = new union(); u.word = 0x0102; Console.WriteLine("lowbyte is: " + u.lowbyte); Console.WriteLine("highbyte is: " + u.highbyte);
The code will output:
lowbyte is: 2 highbyte is: 1
Practical applications
I have used this class – in an expanded version – in several projects. In EKHO I use it to parse the input from the audio port. The data from that port is a byte-stream that contain pairs of bytes, that represent the 16-bit samples. In a project I have done for a company called Kamstrup, it is used to handle data recieved as byte arrays on a serial port.
Generally – Whenever you have code that says something like “a = x*256 + y” or “b = (arr[0]<<8) + arr[1]" you can use a ByteUnion instead and greatly enhance readability.
Additional functionality
The ByteUnion class I have used in real-life projects is much more advanced than this tiny example. The real power of the class is only really obvious when the class is expanded with a constructor that take a byte array as an argument. Also adding stuff like comparison operators and a few interfaces really enhance the usability.
I will return with that in a later post… Now I have work to do

Leave a Reply