考虑以下代码:
public enum MyEnum { V1, V2, V3 }
int size = Marshal.SizeOf(typeof(MyEnum));
它抛出异常:
发生了'System.ArgumentException'类型的未处理异常 TestConsole.exe
其他信息:输入'TestConsole.Program + MyEnum'不能 作为一个不受管理的结构编组;没有意义的大小或偏移可以 计算。
虽然此代码不会抛出异常而size
包含4:
public enum MyEnum { V1, V2, V3 }
public struct MyStruct
{
public MyEnum en;
}
int size = Marshal.SizeOf(typeof(MyStruct));
有谁可以解释为什么.NET框架无法弄清楚第一个示例代码中的enum
是4个字节?
更新
Marshal.Sizeof()
在这个通用方法中失败了:
public bool IoControlReadExact<T>(uint ioControlCode, out T output) where T : struct
{
output = new T();
int outBufferSize = Marshal.SizeOf(typeof(T));
IntPtr outBuffer = Marshal.AllocHGlobal(outBufferSize);
if (outBuffer == IntPtr.Zero)
return false;
try
{
uint bytesReturned;
return IoControlRead(ioControlCode, outBuffer, (uint)outBufferSize, out bytesReturned) && ((uint)outBufferSize == bytesReturned);
}
finally
{
output = (T)Marshal.PtrToStructure(outBuffer, typeof(T));
Marshal.FreeHGlobal(outBuffer);
}
}
编译器没有抱怨enum
不是struct
。
解
我可以重构我的通用方法,使其适用于struct
和enum
:
// determine the correct output type:
Type outputType = typeof(T).IsEnum ? Enum.GetUnderlyingType(typeof(T)) : typeof(T);
//...
int outBufferSize = Marshal.SizeOf(outputType);
//...
output = (T)Marshal.PtrToStructure(outBuffer, outputType);
答案 0 :(得分:25)
这似乎是ECMA-335对枚举的要求之间的差异(ECMA-335 PartitionII§14.3):
......他们应该有自动场布局(§10.1.2); ...
Marshal.SizeOf
的期望:
如果没有结构,可以使用此方法。布局必须是顺序的或明确的。
基于此,您需要在致电Enum.GetUnderlyingType
之前使用Marshal.SizeOf
。
答案 1 :(得分:0)
Marshal.SizeOf(t)
确实想拥有一个非托管结构,而一个枚举是一个托管结构。 .NET可以计算枚举的常量大小:
int size1 = sizeof(MyEnum);
Console.WriteLine("Enum: {0}", size1);
int size2 = Marshal.SizeOf(typeof(MyStruct));
Console.WriteLine("Struct: {0}", size2);