Why doesn't C # have a union?

I am trying to understand the technical aspects of why C # has no unions. I understand that using an attribute mechanism with an explicit arrangement of the structure does the trick, I'm more interested in why this was preferable to the design of the vanilla union.

+4
source share
3 answers

Union resolution undermines .NET security, 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 u.SomeString? What happens if I try to access it? 

C # allows you to shoot in the foot with an unsafe keyword and with certain attributes, but never including managed types. You may have noticed that FieldOffset does not allow combining random types together. Try this with the aforementioned β€œunion."

Here is what I get:

It is not possible to load the type "MyUnion" from the assembly 'ConsoleApplication2, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null' because it contains an object field with an offset of 0, it is incorrectly aligned or overlaps with a field other than the object.

+6
source

Since connections are inherently not type safe and do not contain pointers, the CLR puts a lot of emphasis on 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 can this not work very much (especially on a 64-bit platform), but it also violates so many CLR guarantees that it hurts him to read it.

First, it allows you to get a pointer to an object without actually using pointers, so all unions must be classified by unsafe . Then it also allows you to change this pointer, which can have very funny consequences: for example, if you accidentally change it to the address of another valid list, the garbage collector may decide to move this list around and change the value of your integer without indicating.

It is also completely unsafe. Lists have nothing to do with integers; but since integers look like pointers, this is "not so 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 will it be with your form if you call MyUnion.List.Add (4)? A lot of obvious wreck. Because it is completely unsafe, but unions allow you to believe in it.

+4
source

If you can use reference types in value types, you can use the StructLayout(LayoutKind.Explicit) attribute StructLayout(LayoutKind.Explicit) in your ValueWrapper . I see this tip a few weeks ago here .

+1
source

Source: https://habr.com/ru/post/1315262/


All Articles