代码之家  ›  专栏  ›  技术社区  ›  Fanatic23

为什么c没有工会?

c#
  •  4
  • Fanatic23  · 技术社区  · 14 年前

    我试图理解为什么C没有工会背后的技术细节。我知道使用带有显式结构布局的属性机制可以达到目的,我更感兴趣的是为什么这比普通的联合构造更受欢迎。

    3 回复  |  直到 14 年前
        1
  •  6
  •   wj32    14 年前

    允许联合将破坏.NET的安全性,尤其是在托管对象方面。

    例如(对于32位系统):

    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#允许你用枪射自己的脚吗 不安全的 关键字和具有某些属性,但从不涉及托管类型。您可能已经注意到FieldOffset不允许您将随机类型组合在一起。试试上面的“联合”。

    无法从加载类型“MyUnion” 程序集“控制台应用程序2, PublicKeyToken=null'因为 包含偏移量为0的对象字段 未正确对齐或 与非对象字段重叠。

        2
  •  4
  •   zneak    14 年前

    因为联合本质上既不是类型安全的,也不是指针安全的,而且CLR非常重视这两个问题。

    union MyUnion
    {
        private List<int> myList;
        private int integer;
    
        public MyUnion(int foo) { integer = foo; }
        public List<int> List { get { return myList; } }
    }
    

    这不仅非常不起作用(尤其是在64位平台下),而且还破坏了CLR的许多保证,以至于读起来很痛苦。

    首先,它允许您在不实际使用指针的情况下获取指向对象的指针,因此需要对联合进行分类 unsafe . 然后,它还允许您更改此指针,这可能会产生非常有趣的含义:例如,如果您不小心将其更改为另一个有效列表的地址,垃圾收集器可能会决定将此列表四处移动,并更改整数的值,而无需告知。

    这也是完全不安全的类型。列表与整数无关;但由于整数看起来像指针,这“没那么糟”。现在,考虑以下示例:

    union MyUnion
    {
        private List<int> myList;
        private Form myForm;
    
        public MyUnion(Form theForm) { myForm = theForm; }
    
        public List<int> List { get { return myList; } }
    }
    

    如果你把MyUnion.List.Add(4)叫做MyUnion.List.Add,那你的表单会怎么处理?很明显,撞车。因为这是完全不安全的类型,但工会让你相信它是安全的。

        3
  •  1
  •   Community CDub    7 年前

    StructLayout(LayoutKind.Explicit) 属性 ValueWrapper . 几周前我看到了这个提示 here .