Marshal.SizeOf throws ArgumentException on enums
.net, c#, enums, marshalling
Solution
This appears to be a limitation imposed by a difference between the requirements of ECMA-335 for enums (ECMA-335 Partition II §14.3):
...they shall have auto field layout (§10.1.2); ...
And the expectations of `Marshal.SizeOf`:
You can use this method when you do not have a structure. The layout must be sequential or explicit.
Based on this, you will need to use `Enum.GetUnderlyingType` before calling `Marshal.SizeOf`.
Problem
Consider this code: ``` public enum MyEnum { V1, V2, V3 } int size = Marshal.SizeOf(typeof(MyEnum)); ``` it throws the exception: An unhandled exception of type 'System.ArgumentException' occurred in TestConsole.exe Additional information: Type 'TestConsole.Program+MyEnum' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed. While this code doesn't throw an exception and `size` contains 4: ``` public enum MyEnum { V1, V2, V3 } public struct MyStruct { public MyEnum en; } int size = Marshal.SizeOf(typeof(MyStruct)); ``` Can anyone explain why the .NET framework can't figure out that the `enum` is 4 bytes in the first sample code? UPDATE `Marshal.Sizeof()` failed on me in this generic method: ``` 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); } } ``` And the compiler didn't complain about `enum` not being a `struct`. SOLUTION I could refactor my generic method to make it work for both `struct` and `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); ```