我正在将一个用 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 位整数字节的一种(多种)方法。
另一种是结构中的数据来自外部源,例如网络数据包。通常,包含联合的结构的一个元素是一个 ID,它告诉您联合的哪种风格有效。
在这两种情况下,您都不能盲目地忽略联合并将其转换为两个(或更多)字段不重合的结构。
在 C/C++ 中,联合用于覆盖同一内存位置中的不同成员,所以如果你有一个 int 和一个 float 的联合,它们都使用相同的 4 字节内存来存储,显然写入一个会破坏另一个(因为int 和 float 有不同的位布局)。
在 .Net 中,Microsoft 选择了更安全的选择,并且没有包含此功能。
编辑:除了互操作
如果您使用 将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 可以节省 32 位由 int 分配的内存......这些天不会制造或破坏应用程序。
public class Foo
{
public float bar;
public int killroy;
public float fubar
{
get{ return (float)killroy;}
set{ killroy = (int)value;}
}
}