W wielu aukcjach MSIL zauważyłem, co następuje:
System.Nullable`1<!0> etc ...
lub
class !0 etc ...
Jakie jest znaczenie !0
w tych okolicznościach?
Odpowiedzi:
To jest dziwactwo dekompilatora, którego używasz do oglądania zestawu .NET. Jest to zachowanie ildasm.exe, inne, takie jak Reflector lub ILSpy, robią to dobrze. Programista Microsoft, który to napisał, skorzystał ze skrótu, generuje ciąg z IL, który po prostu wyświetla argument typu w sposób, w jaki jest zakodowany, bez pisania dodatkowego kodu do wyszukiwania nazwy argumentu typu w metadanych.
Musisz odczytywać !n
jako n-ty argument typu ogólnego. Gdzie! 0 oznacza „argument pierwszego typu”,! 1 oznacza „argument drugiego typu” itd. W przypadku Nullable <> wiesz, że „! 0” oznacza „T” z artykułu MSDN.
Możesz również napotkać coś takiego !!T
. Dwa wykrzykniki wskazują argument typu dla metody ogólnej . Tym razem ildasm.exe ma wyszukać nazwę argumentu typu zamiast używać !!0
. Dlaczego programista wybrał skrót do typów ogólnych, ale nie do metod ogólnych, jest trudny do odtworzenia. Ildasm to dość dziwaczny program napisany w stylu C ++, który bardzo różni się od innych kodów C ++ w .NET. Nie tak zdyscyplinowane, niezerowe szanse, że to zadanie stażysty :)
Przyrostek `1 w polu„ Nullable ”jest normalnym kodowaniem dla nazw typów ogólnych, wskazuje, że typ ogólny ma jeden argument typu. Innymi słowy, dla Nullable <> nigdy nie zobaczysz! 1 używanego.
Więc po prostu czytaj !0
jako „T”. Lub użyj lepszego dekompilatora.
To jest parametr typu ogólnego.
Są pozycyjne.
Zdekompiluj kod ogólny, aby zobaczyć, jak są używane (porównaj IL z C #).
ldfld class System.Collections.Generic.Dictionary``2<!0, !1> valuetype System.Collections.Generic.Dictionary``2/Enumerator<!TKey, !TValue>::dictionary
lub call instance void class System.Collections.Generic.Dictionary``2<!TKey, !TValue>::Insert(!0, !1, bool)
. Surowy IL i tak używa tylko argumentu pozycyjnego - !TKey
jest to już próba uczynienia IL bardziej czytelną. Może nie zawsze działa dobrze? Specyfikacja ECMA zawsze używa również pozycji !0
/ !00
.
!T
i!!T
, w zależności od tego, czy parametr generyczny należy do klasy zawierającej, czy do metody ... To samo, jeśli używam ildasm