Questi sono dettagli di implementazione non documentati del compilatore e soggetti a modifiche in qualsiasi momento. (AGGIORNAMENTO: vedere GeneratedNames.cs
nelle fonti C # per i dettagli correnti; la descrizione di seguito è un po 'obsoleta.)
Tuttavia, dato che sono un bravo ragazzo, ecco alcuni di quei dettagli:
Se hai una variabile locale inutilizzata che l'ottimizzatore rimuove, emettiamo comunque le informazioni di debug per essa nel PDB. Abbiamo applicato il suffisso __Deleted$
a tali variabili in modo che il debugger sappia che erano nel codice sorgente ma non rappresentate nel binario.
Agli slot di variabili temporanee allocati dal compilatore vengono assegnati nomi con il pattern CS $ X $ Y, dove X è il "tipo temporaneo" e Y è il numero di temporanei assegnati finora. I tipi temporanei sono:
0 --> short lived temporaries
1 --> return value temporaries
2 --> temporaries generated for lock statements
3 --> temporaries generated for using statements
4 --> durable temporaries
5 --> the result of get enumerator in a foreach
6 --> the array storage in a foreach
7 --> the array index storage in a foreach.
I tipi temporanei tra 8 e 264 sono archivi di indici di array aggiuntivi per array multidimensionali.
I tipi temporanei sopra 264 sono usati per i provvisori che coinvolgono l'istruzione fissa che fissa una stringa.
Vengono generati nomi speciali generati dal compilatore per:
1 --> the iterator state ("state")
2 --> the value of current in an iterator ("current")
3 --> a saved parameter in an iterator
4 --> a hoisted 'this' in an iterator ("this")
5 --> a hoisted local in an iterator
6 --> the hoisted locals from an outer scope
7 --> a hoisted wrapped value ("wrap")
8 --> the closure class instance ("locals")
9 --> the cached delegate instance ("CachedAnonymousMethodDelegate")
a --> the iterator instance ("iterator")
b --> an anonymous method
c --> anonymous method closure class ("DisplayClass")
d --> iterator class
e --> fixed buffer struct ("FixedBuffer")
f --> anonymous type ("AnonymousType")
g --> initializer local ("initLocal")
h --> query expression temporary ("TransparentIdentifier")
i --> anonymous type field ("Field")
j --> anonymous type type parameter ("TPar")
k --> auto prop field ("BackingField")
l --> iterator thread id
m --> iterator finally ("Finally")
n --> fabricated method ("FabricatedMethod")
o --> dynamic container class ("SiteContainer")
p --> dynamic call site ("Site")
q --> dynamic delegate ("SiteDelegate")
r --> com ref call local ("ComRefCallLocal")
s --> lock taken local ("LockTaken")
Lo schema per generare nomi magici è: P<N>C__SI
dove:
- P è CS $ per i delegati memorizzati nella cache e le istanze di classi di visualizzazione, altrimenti vuoto.
- N è il nome originale associato all'oggetto, se esiste
- C è il carattere da 1 a s sopra elencati
- S è un suffisso descrittivo ("corrente", "stato" e così via) in modo da non dover memorizzare la tabella sopra durante la lettura dei metadati.
- I è un numero univoco opzionale