February 16th, 2009
Uncommon C# : Using C style unions in C# - 1

A union is a data structure that stores several different types of data at the same single location in memory. Although this might sound like madness in a garbage collected world many older binary data formats still heavily rely on this. A possible use is if you want to modify an IPv4 address. An IPv4 address is 4 bytes, or an unsigned C# int. You might want to manipulate the IP address as a single value, or by splitting it into four separate bytes.
C# does not have a union keyword like C or C++ but it is still possible to create the same result by using the StructLayout(LayoutKind.Explicit) and FieldOffset attributes which are part of System.Runtime.InteropServices (which as the name suggests supplies code for working with unmanaged code).
C# allows for three distinct ways of layout data structures in memory: Auto, Explicit, and Sequential. The default is “Auto”, but for this to work we need “Explicit”.
The FieldOffset sets the physical position of fields within the representation of a class or structure. But what it also allow you to do is to set the same position twice. In the below example we will let the unsigned int for the IP address start at the same spot as the most significant byte.
using System;
using System.Runtime.InteropServices;
namespace ipv4
{
[StructLayout(LayoutKind.Explicit)]
struct IPv4Address
{
[FieldOffset(0)]
public uint Address;
[FieldOffset(0)]
public byte b3;
[FieldOffset(1)]
public byte b2;
[FieldOffset(2)]
public byte b1;
[FieldOffset(3)]
public byte b0;
}
class MainClass
{
public static void Main(string[] args)
{
IPv4Address myAddress;
// Assign localhost to the IPv4 address
myAddress.Address = 0; // Avoid CS0170: Unassigned Field error
myAddress.b0 = 127;
myAddress.b1 = 0;
myAddress.b2 = 0;
myAddress.b3 = 1;
Console.WriteLine("The address in hexadecimal: {0:x}",myAddress.Address);
}
}
}
Image credit: Jeff Belmonte









Except where otherwise noted, content on this site is
February 23rd, 2009 at 7:57 pm
Was using LayoutKind.Explicit the other day, whilst coding up a struct which held a PCX Image Header. Was thinking I could load the header into a byte array sitting at FieldOffset 0, and then have relevant fields such as XMax, YMax etc. populated according to their corresponding field offsets.
Alas, you can’t use reference types like a byte array with LayoutKind.Explicit! (It’ll compile it for you, though). Makes sense when you think about it, but was annoying all the same.