C#中的C++联合

Vik*_*son 70 c# c++ unions

我正在将用C++编写的库翻译成C#,关键字"union"只存在一次.在结构中.

将它翻译成C#的正确方法是什么?它做了什么?它看起来像这样;

struct Foo {
    float bar;

    union {
        int killroy;
        float fubar;
    } as;
}
Run Code Online (Sandbox Code Playgroud)

Arm*_*her 76

您可以使用显式字段布局:

[StructLayout(LayoutKind.Explicit)] 
public struct SampleUnion
{
    [FieldOffset(0)] public float bar;
    [FieldOffset(4)] public int killroy;
    [FieldOffset(4)] public float fubar;
}
Run Code Online (Sandbox Code Playgroud)

未经测试.这个想法是两个变量在你的结构中具有相同的位置.你当然只能使用其中一个.

关于结构教程中的联合的更多信息

  • 它是否适用于值类型(如枚举)或原始类型? (11认同)
  • 请注意,仅当涉及的类型是基本类型(如int和float)时,这才有效.一旦涉及到对象,它就不会让你. (6认同)
  • “当然,你只能使用其中之一。” 可能不清楚。您可以访问和设置它们,但它们会相互覆盖。我想澄清这一点。 (2认同)

Ste*_*ows 22

如果不知道如何使用它,你无法真正决定如何处理它.如果它仅用于节省空间,那么您可以忽略它并只使用结构.

然而,这通常不是使用工会的原因.使用它们有两个常见的原因.一种是提供两种或更多种访问相同数据的方法.例如,int和4个字节数组的并集是分离出32位整数字节的一种(多种)方法.

另一种是结构中的数据来自外部源,例如网络数据包.通常,包含联合的结构的一个元素是一个ID,它告诉您联合的哪种风格有效.

在这两种情况下,你都不能盲目地忽略联合并将其转换为两个(或更多)字段不重合的结构.

  • 我认为在Steve的回答中重要的是,你真的需要了解你正在移植的特定联盟的用法.C#中可能还有其他构造可以更优雅的方式满足需求. (3认同)
  • 虽然我理解 @AaronLS 的意思,但最好能提供一个文档链接或有关在 C# 中_优雅地_执行此操作的常用方法的链接。我可以猜测一些非常基本的方法,具体取决于用法,例如使用属性返回联合的一个值的“转换”,因为它是另一个成员。但想知道对于常见场景还有哪些其他优雅的方式。 (3认同)

Nir*_*Nir 6

在 C/C++ 中,联合用于覆盖同一内存位置中的不同成员,因此,如果您有一个 int 和一个 float 的联合,它们都使用相同的 4 字节内存来存储,显然写入一个会破坏另一个(因为int 和 float 有不同的位布局)。

在.Net 中,微软选择了更安全的选择,并且没有包含此功能。

编辑:除了互操作

  • 显式布局结构的使用不限于互操作。非引用类型的基元和公共成员可以以任意方式覆盖非引用类型的其他基元和公共成员,并具有完全定义的行为,无论代码是否将相关结构传递给外部代码。在这方面,.NET 支持比“现代”C 更低级别的构造。 (2认同)