Marshal.SizeOf在枚举上抛出ArgumentException

考虑这个代码:

public enum MyEnum { V1, V2, V3 } int size = Marshal.SizeOf(typeof(MyEnum)); 

它抛出exception:

TestConsole.exe中出现未处理的“System.ArgumentException”typesexception

附加信息:types'TestConsole.Program + MyEnum'不能作为非托pipe结构编组; 没有意义的大小或偏移量可以计算出来。

虽然这段代码不会抛出exception,但size包含4:

 public enum MyEnum { V1, V2, V3 } public struct MyStruct { public MyEnum en; } int size = Marshal.SizeOf(typeof(MyStruct)); 

任何人都可以解释为什么.NET框架不能找出第一个示例代码中的enum是4字节?

UPDATE

Marshal.Sizeof()在这个generics方法中失败了:

 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

我可以重构我的generics方法,使其工作的structenum

 // 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); 

这似乎是ECMA-335对于枚举的要求(ECMA-335分割II第14.3节)之间的差异所施加的限制:

…他们应该有自动场布局(§10.1.2); …

Marshal.SizeOf的期望:

当你没有结构时,你可以使用这个方法。 布局必须是顺序的或明确的。

基于此,您需要在调用Marshal.SizeOf之前使用Enum.GetUnderlyingType

Marshal.SizeOf(t)确实希望有一个非托pipe结构,而枚举是一个托pipe结构。 .NET可以计算一个枚举的常量大小:

 int size1 = sizeof(MyEnum); Console.WriteLine("Enum: {0}", size1); int size2 = Marshal.SizeOf(typeof(MyStruct)); Console.WriteLine("Struct: {0}", size2);