I am trying to understand the technicalities behind why C# does not have unions. I understand that using the attribute mechanism with explicit structure layout does the trick, I am more interested in why this was preferred over vanilla union construct.
Allowing unions would undermine the safety of .NET, especially when it comes to managed objects.
For example (for 32-bit systems):
union MyUnion
{
string SomeString; // just a 4 byte pointer
uint SomeInteger;
}
MyUnion u;
u.SomeInteger = 0x98765432;
// What's u.SomeString? What happens if I try to access it?
C# does allow you to shoot yourself in the foot with the unsafe keyword and with certain attributes, but never involving managed types. You might have noticed that FieldOffset doesn't let you combine random types together. Try it with the above "union".
Here's what I get:
Could not load type 'MyUnion' from assembly 'ConsoleApplication2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field.
Because unions are inherently not type-safe nor pointer-safe, and the CLR puts great emphasis over both.
Consider the following:
union MyUnion
{
private List<int> myList;
private int integer;
public MyUnion(int foo) { integer = foo; }
public List<int> List { get { return myList; } }
}
Not only this can very much not work (notably under a 64 bits platform), but it also breaks so many guarantees of the CLR that it hurts to read it.
First, it allows you to get the pointer to the object without actually using pointers, so unions would all need to be classified unsafe
. Then, it also lets you change this pointer, which can have very funny implications: for instance, if you accidentally change it to the address of another valid list, the garbage collector might decide to move this list around, and change the value of your integer without telling.
This is also completely type-unsafe. Lists have nothing to do with integers; but since integers look like pointers, this is "not that bad". Now, consider the following example:
union MyUnion
{
private List<int> myList;
private Form myForm;
public MyUnion(Form theForm) { myForm = theForm; }
public List<int> List { get { return myList; } }
}
Now what is that gonna do with your form if you call MyUnion.List.Add(4)? Much obviously, crash. Because this is completely type-unsafe, but unions let you believe it's safe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With