SORU
26 Temmuz 2013, Cuma


Neden Mareşal yapar.Boyutu çeteleler üzerinde ArgumentException atmak?

Bu örnek kodu göz önünde bulundurun:

public enum MyEnum { V1, V2, V3 }

int size = Marshal.SizeOf(typeof(MyEnum));

bu özel durum atar:

Bu işlenmeyen bir özel durum türü 'System.ArgumentException' oluştu TestConsole.exe

Ek bilgi: Tür 'TestConsole.Program MyEnum' olamaz yönetilmeyen bir yapı olarak sıralanmış; anlamlı bir boyut veya ofset hesaplanan.

Bu kod atmaz da bir istisna ve size 4 içerir:

public enum MyEnum { V1, V2, V3 }

public struct MyStruct
{
    public MyEnum en;
}

int size = Marshal.SizeOf(typeof(MyStruct));

Herkes neden açıklayabilir .NET çerçeve enum ilk örnek kodu 4 bayt olduğunu anlamaya olabilir mi?

GÜNCELLEME

Garip bir şey enum Marshal.Sizeof() Bu genel yöntem beni başarısız oldu, çünkü derleyici tarafından struct olarak görülür

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

Ve derleyici enum struct bir değil varlık hakkında şikayet etmedi.

ÇÖZÜM

Birçok cevaplar için teşekkürler. Bu yapılar VE numaralamalar için çalışmasını sağlamak için genel yöntemim yeniden yapabilirim:

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

CEVAP
26 Temmuz 2013, Cuma


Bu bir sınırlama numaralamalar için ECMA-335 gereksinimleri arasında bir fark (ECMA-335 Bölüm II §14.3) tarafından dayatılan görünüyor:

...otomatik alan düzeni (§10.1.2) onların olacaktır; ...

Ve Marshal.SizeOf beklentiler:

Bir yapısı varsa, bu yöntemi kullanabilirsiniz. Düzeni sıralı veya açık olması gerekir.

Buna göre, Marshal.SizeOf aramadan önce Enum.GetUnderlyingType kullanmak gerekir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:
C#

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • andyabc45

    andyabc45

    1 Mayıs 2011
  • colacas

    colacas

    29 EKİM 2006
  • HBO

    HBO

    17 Mayıs 2006