【发布时间】:2016-07-21 15:35:45
【问题描述】:
在 .NET Core 中,只有一个通用方法 Marshal.SizeOf<T>() 可用(Marshal.SizeOf(Type t) 已弃用)。但我想枚举一个类的所有属性并获取它们的编组大小。我该怎么办?
这是我的代码:(实际上不是我的,而是我尝试移植到 .NET Core 的代码)
来自 https://github.com/kapetan/dns/blob/master/DNS/Protocol/Marshalling/Struct.cs 的修改
private static byte[] ConvertEndian<T>(byte[] data)
{
var fields = typeof(T).GetRuntimeFields().Where(f => f.IsStatic == false);
EndianAttribute endian = typeof(T).GetTypeInfo().GetCustomAttribute<EndianAttribute>();
foreach (FieldInfo field in fields)
{
if (endian == null && field.GetCustomAttribute<EndianAttribute>(false) == null)
{
continue;
}
int offset = Marshal.OffsetOf<T>(field.Name).ToInt32();
// *** This is deprecated ***
// int length = Marshal.SizeOf(field.FieldType);
// *** This doesn't work at all ***
int length = field.FieldType.GetTypeInfo().StructLayoutAttribute.Size;
endian = endian ?? field.GetCustomAttribute<EndianAttribute>(false);
if (endian.Endianness == Endianness.Big && BitConverter.IsLittleEndian ||
endian.Endianness == Endianness.Little && !BitConverter.IsLittleEndian)
{
Array.Reverse(data, offset, length);
}
}
return data;
}
【问题讨论】:
-
您不应该编写这样的代码,它从根本上与提前编译(又名 .NET Native)不兼容。这在 .NETCore 中非常重要,数百个小程序集完全杀死了冷启动时间。不是说你不能这样做,BinaryReader 还可以让你读取网络数据包。