我在C#中声明类似于C ++中的union:
[StructLayout(LayoutKind.Explicit, Size = 5)]
public struct Marker
{
[FieldOffset(0)] public byte label;
[FieldOffset(1)] public int count;
[FieldOffset(1)] private byte count_0;
[FieldOffset(2)] private byte count_1;
[FieldOffset(3)] private byte count_2;
[FieldOffset(4)] private byte count_3;
}
此外,我的byte[] bytes
大小为5.我需要将我的数组转换为Marker对象。我可以通过以下方式实现:
var marker = new Marker
{
label = bytes[0],
count = BitConverter.ToInt32(bytes, 1)
}
或者:
var marker = new Marker
{
label = bytes[0],
count_0 = bytes[1],
count_1 = bytes[2],
count_2 = bytes[3],
count_3 = bytes[4]
}
没关系,但我认为可以通过更优化的方式从性能视图开始 - 只需将marker
指向bytes
的第一个字节。我试图找到这样的东西:
BitConverter.To<Marker>(bytes);
如何通过一次操作将字节数组转换为union结构?
答案 0 :(得分:1)
这应该有效
static void Main(string[] args)
{
//Creating test data
List<byte> data = new List<byte>();
data.Add(123);
data.AddRange(BitConverter.GetBytes((int)123456));
//Converting test data to Struct
Marker m = StructFromBytes<Marker>(data.ToArray());
//Check if it works
Console.WriteLine(m.label); //Prints 123
Console.WriteLine(m.count); //Prints 123456
}
private static T StructFromBytes<T>(byte[] bytes)
{
int structSize = Marshal.SizeOf(typeof(T));
byte[] structBytes = new byte[structSize];
Array.Copy(bytes, 0, structBytes, 0, structSize);
GCHandle handle = GCHandle.Alloc(structBytes, GCHandleType.Pinned);
T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
handle.Free();
return theStructure;
}
答案 1 :(得分:0)
您可以创建构造函数:
[StructLayout(LayoutKind.Explicit, Size = 5)]
public struct Marker
{
[FieldOffset(0)] public byte label;
[FieldOffset(1)] public int count;
[FieldOffset(1)] private byte count_0;
[FieldOffset(2)] private byte count_1;
[FieldOffset(3)] private byte count_2;
[FieldOffset(4)] private byte count_3;
public Marker(byte[] bytes)
{
label = bytes[0];
count_0 = bytes[1];
count_1 = bytes[2];
count_2 = bytes[3];
count_3 = bytes[4];
}
}
或运算符重载:
[StructLayout(LayoutKind.Explicit, Size = 5)]
public struct Marker
{
[FieldOffset(0)] public byte label;
[FieldOffset(1)] public int count;
[FieldOffset(1)] private byte count_0;
[FieldOffset(2)] private byte count_1;
[FieldOffset(3)] private byte count_2;
[FieldOffset(4)] private byte count_3;
public static explicit operator Marker(byte[] bytes)
{
Marker result = new Marker();
result.label = bytes[0];
result.count_0 = bytes[1];
result.count_1 = bytes[2];
result.count_2 = bytes[3];
result.count_3 = bytes[4];
return result;
}
}
这两种解决方案都可以使您的结构创建一个单行:
Marker marker = new Marker(bytes);
Marker marker = (Marker)bytes;