Union Types in C# can also contain Struct fields C# with Example



Union Types in C# can also contain Struct fields C# with Example

Apart from primitives, the Explicit Layout structs (Unions) in C#, can also contain other Structs. As long as a field is a 
Value type and not a Reference, it can be contained in a Union: 
using System; 
using System.Runtime.InteropServices; 
// The struct needs to be annotated as "Explicit Layout" 
[StructLayout(LayoutKind.Explicit)] 
struct IpAddress 
{ 
// Same definition of IpAddress, from the example above 
} 
// Now let's see if we can fit a whole URL into a long 
// Let's define a short enum to hold protocols 
enum Protocol : short { Http, Https, Ftp, Sftp, Tcp } 
// The Service struct will hold the Address, the Port and the Protocol 
[StructLayout(LayoutKind.Explicit)] 
struct Service 
{ 
[FieldOffset(0)] public IpAddress Address; 
[FieldOffset(4)] public ushort Port; 
[FieldOffset(6)] public Protocol AppProtocol; 
[FieldOffset(0)] public long Payload; 
public Service(IpAddress address, ushort port, Protocol protocol) 
{ 
Payload = 0; 
Address = address; 
Port = port; 
AppProtocol = protocol; 
} 
public Service(long payload) 
{ 
Address = new IpAddress(0); 
Port = 80; 
AppProtocol = Protocol.Http; 
Payload = payload; 
} 
public Service Copy() => new Service(Payload); 
public override string ToString() => $"{AppProtocol}//{Address}:{Port}/"; 
} 
We can now verify that the whole Service Union fits into the size of a long (8 bytes). 
var ip = new IpAddress(new Random().Next()); 
Console.WriteLine($"Size: {Marshal.SizeOf(ip)} bytes. Value: {ip.Address} = {ip}."); 
var s1 = new Service(ip, 8080, Protocol.Https); 
var s2 = new Service(s1.Payload); 
s2.Address.Byte1 = 100; 
s2.AppProtocol = Protocol.Ftp; 
 

Console.WriteLine($"Size: {Marshal.SizeOf(s1)} bytes. Value: {s1.Address} = {s1}."); 
Console.WriteLine($"Size: {Marshal.SizeOf(s2)} bytes. Value: {s2.Address} = {s2}."); 
View Demo 
 

0 Comment's

Comment Form