Perché! 0 è un tipo in Microsoft Intermediate Language (MSIL)?


88

In molti elenchi MSIL, ho osservato quanto segue:

System.Nullable`1<!0> etc ...

o

class !0 etc ...

Qual è il significato !0in queste circostanze?

Risposte:


118

Questa è la stranezza del decompilatore che usi per guardare un assembly .NET. È il comportamento di ildasm.exe, altri come Reflector o ILSpy lo fanno bene. Il programmatore Microsoft che l'ha scritto ha preso una scorciatoia, genera una stringa dall'IL che visualizza semplicemente l'argomento di tipo nel modo in cui è codificato, senza scrivere il codice aggiuntivo per cercare il nome dell'argomento di tipo nei metadati.

È necessario leggere !ncome argomento di tipo n-esimo del tipo generico. Dove! 0 significa "argomento del primo tipo",! 1 significa "argomento del secondo tipo", eccetera. Per Nullable <>, sai che "! 0" significa "T" dall'articolo di MSDN.

Potresti anche incontrare qualcosa di simile !!T. Due punti esclamativi indicano un argomento di tipo per un metodo generico . Questa volta, ildasm.exe non cercare il nome argomento di tipo invece di utilizzare !!0. Perché il programmatore ha scelto la scorciatoia su tipi generici ma non su metodi generici è difficile da decodificare. Ildasm è un programma piuttosto stravagante ed è scritto in uno stile di codifica C ++ molto diverso da altri codici C ++ in .NET. Non così disciplinato, probabilità diverse da zero che questo fosse il compito di uno stagista :)

Il suffisso `1 su" Nullable "è una normale codifica per nomi di tipi generici, indica che il tipo generico ha un argomento di tipo. In altre parole, per Nullable <> non vedrai mai! 1 utilizzato.

Quindi leggi semplicemente !0come "T". Oppure usa un decompilatore migliore.


35

Questo è un parametro di tipo generico.

Sono posizionali.

Decompilare del codice generico per vedere come vengono utilizzati (confrontare IL vs C #).


5
Se uso TryRoslyn non capisco ... goo.gl/ZZKE38 ottengo !Te !!T, a seconda se il parametro generico è della classe contenente o del metodo ... Lo stesso se uso ildasm
xanatos

@xanatos Non sempre. Vedo anche codice come ldfld class System.Collections.Generic.Dictionary``2<!0, !1> valuetype System.Collections.Generic.Dictionary``2/Enumerator<!TKey, !TValue>::dictionaryo call instance void class System.Collections.Generic.Dictionary``2<!TKey, !TValue>::Insert(!0, !1, bool). Comunque, l'IL grezzo usa solo l'argomento posizionale - !TKeyè già un tentativo di rendere l'IL più leggibile. Forse non funziona sempre bene? La specifica ECMA usa sempre anche la !0/ di posizione !00.
Luaan
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.