c# linguaggio - Perché è! 0 un tipo in Microsoft Intermediate Language (MSIL)?





interpretato visual (3)


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

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

Potresti anche incontrare qualcosa come !!T Due punti esclamativi indicano un argomento di tipo per un metodo generico. Questa volta, ildasm.exe cerca il nome dell'argomento type invece di usare !!0 . Perché il programmatore ha preso il collegamento su tipi generici ma non su metodi generici è difficile da decodificare. Ildasm è un programma piuttosto bizzarro ed è scritto in uno stile di codifica C ++ che è molto diverso dagli altri codici C ++ in .NET. Non è così disciplinato, non zero probabilità che questo è stato un compito di 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 in uso.

Quindi leggi semplicemente !0 come "T". O usare un decompilatore migliore.

In molti annunci MSIL ho osservato quanto segue:

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

o

class !0 etc ...

Qual è il significato di !0 in queste circostanze?




Questo è un parametro di tipo generico.

Sono posizionali.

Decompila un codice generico per vedere come vengono utilizzati (confronta IL vs C #).




In realtà è molto difficile implementare correttamente GetHashCode() perché, oltre alle regole che Marc ha già menzionato, il codice hash non dovrebbe cambiare durante la vita di un oggetto. Pertanto i campi che vengono utilizzati per calcolare il codice hash devono essere immutabili.

Alla fine ho trovato una soluzione a questo problema quando lavoravo con NHibernate. Il mio approccio è quello di calcolare il codice hash dall'ID dell'oggetto. L'ID può essere impostato solo con il costruttore, quindi se vuoi cambiare l'ID, il che è molto improbabile, devi creare un nuovo oggetto che ha un nuovo ID e quindi un nuovo codice hash. Questo approccio funziona meglio con GUID perché è possibile fornire un costruttore senza parametri che genera in modo casuale un ID.





c# .net cil