Rozważmy kod:Marshal.SizeOf wyrzuca ArgumentException na teksty stałe
public enum MyEnum { V1, V2, V3 }
int size = Marshal.SizeOf(typeof(MyEnum));
zgłasza wyjątek:
nieobsługiwany wyjątek typu 'System.ArgumentException' w module TestConsole.exe
Dodatkowe informacje: Wpisz "TestConsole.Program + MyEnum" nie może być marszałka jako struktura niezarządzana; nie można obliczyć żadnego znaczącego rozmiaru ani przesunięcia.
Chociaż ten kod nie wyjątek i size
zawiera 4:
public enum MyEnum { V1, V2, V3 }
public struct MyStruct
{
public MyEnum en;
}
int size = Marshal.SizeOf(typeof(MyStruct));
Może ktoś wyjaśnić, dlaczego NET nie może dowiedzieć się, że enum
wynosi 4 bajty w pierwszej próbce kod?
UPDATE
Marshal.Sizeof()
zawiodły mnie w tej metody rodzajowe:
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);
}
}
i kompilator nie narzekają enum
nie będąc struct
.
ROZWIĄZANIE
mogłem byłaby moja metoda rodzajowa, aby pracować zarówno struct
i 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);
[this] (http://stackoverflow.com/questions/4219413/c-sharp-sizeofenum-alternative-to-workaround-resharper-false-error) nie wyjaśnia, dlaczego, ale podaje obejście. –
W przeciwieństwie do tego, możliwe jest utworzenie typu wskaźnika na "MyEnum", z niebezpiecznym kodem, który używa typu 'MyEnum *'. –