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

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

struct Foo {
    float bar;

    union {
        int killroy;
        float fubar;
    } as;
}
有帮助吗?

解决方案

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

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

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

有关结构教程中的联盟的更多信息

其他提示

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

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

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

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

在C / C ++中,union用于在同一个内存位置覆盖不同的成员,所以如果你有一个int和float的并集,它们都使用相同的4字节内存来存储,显然写入一个就会破坏其他(因为int和float有不同的位布局)。

在.Net中,微软采用了更安全的选择,并未包含此功能。

编辑:除了互操作

如果你使用 union 将其中一种类型的字节映射到另一种类型,那么在C#中你可以使用 BitConverter 代替。

float fubar = 125f; 
int killroy = BitConverter.ToInt32(BitConverter.GetBytes(fubar), 0);

int killroy = 125;
float fubar = BitConverter.ToSingle(BitConverter.GetBytes(killroy), 0);

就个人而言,我会一起忽略UNION,并将Killroy和Fubar作为单独的字段实施

public struct Foo
{
    float bar;
    int Kilroy;
    float Fubar;
}

使用UNION可以节省由int分配的32位内存....这些天不会创建或破坏应用程序。

public class Foo
{
    public float bar;
    public int killroy;

    public float fubar
    {
        get{ return (float)killroy;}
        set{ killroy = (int)value;}
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top