C # 中的 C + + 联合

我正在把一个用 C + + 写的库翻译成 C # ,关键字“ union”只存在一次。

把它翻译成 C # 的正确方法是什么

struct Foo {
float bar;


union {
int killroy;
float fubar;
} as;
}
60528 次浏览

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

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

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

更多关于 Struct 教程中工会的信息

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

在.Net 中,微软选择了更安全的选择,并且没有包含这个特性。

编辑: 除了互操作

就个人而言,我会忽略所有的联盟一起,并实施基尔罗伊和 Fubar 作为单独的领域

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

使用 UNION 可以节省 int... 所分配的32位内存。

在不知道如何使用它的情况下,您无法真正决定如何处理它。如果它只是用于节省空间,那么您可以忽略它,只使用 struct。

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

另一种是当结构中的数据来自外部源(如网络数据包)时。通常,包含联合的结构的一个元素是一个 ID,它告诉您联合的哪种风格正在生效。

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

如果使用 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);
public class Foo
{
public float bar;
public int killroy;


public float fubar
{
get{ return (float)killroy;}
set{ killroy = (int)value;}
}
}

您可以编写一个简单的包装器,但是在大多数情况下,只使用一个对象就不会那么令人困惑了。

    public class MyUnion
{
private object _id;
public T GetValue<T>() => (T)_id;
public void SetValue<T>(T value) => _id = value;
}