2010-03-24 4 views
96

Wenn Sie jemals Reflector verwendet haben, haben Sie wahrscheinlich bemerkt, dass der C# -Compiler Typen, Methoden, Felder und lokale Variablen generiert, die vom Debugger eine 'spezielle' Darstellung verdienen. Zum Beispiel werden lokale Variablen, die mit 'CS $' beginnen, dem Benutzer nicht angezeigt. Es gibt weitere spezielle Namenskonventionen für Schließtypen von anonymen Methoden, die Unterstützung von Feldern für automatische Eigenschaften und so weiter.Wissenswertes über VS-Debugger 'magische Namen'

Meine Frage: Wo erfahren Sie über diese Namenskonventionen? Weiß jemand etwas über Dokumentation?

Mein Ziel ist es, PostSharp 2.0 die gleichen Konventionen zu verwenden.

Antwort

190

Dies sind undokumentierte Implementierungsdetails des Compilers und können jederzeit geändert werden. (UPDATE: Siehe GeneratedNames.cs in den C# Quellen für die aktuellen Einzelheiten, die Beschreibung unten ist etwas out-of-date.)

Da ich ein netter Kerl bin, hier einige dieser Details sind:

Wenn Sie eine nicht verwendete lokale Variable haben, die das Optimierungsprogramm entfernt, geben wir Debug-Informationen dafür trotzdem in die PDB aus. Wir steckten das Suffix __Deleted$ auf solche Variablen, so dass der Debugger weiß, dass sie im Quellcode waren, aber nicht in der Binärdatei dargestellt.

Temporäre Variablenplätze, die vom Compiler zugewiesen werden, erhalten Namen mit dem Muster CS $ X $ Y, wobei X die "temporäre Art" und Y die Anzahl der bisher zugewiesenen Provisorien ist. Die temporären Arten sind:

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. 

Temporary Arten zwischen 8 und 264 zusätzliche Feldindex Speichern für mehrdimensionale Arrays sind.

Temporäre Arten über 264 werden für Provisorien verwendet, bei denen die feste Anweisung eine Zeichenfolge festlegt.

Spezielle Compiler generierten Namen werden erstellt für:

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") 

Das Muster magischen Namen für die Erzeugung ist: P<N>C__SI Wo:

  • P CS $ Instanzen für Cache-Delegierten und Anzeigeklasse ist, leer Andernfalls.
  • N ist der ursprüngliche Name mit der Sache assoziiert, falls vorhanden
  • C das Zeichen 1 bis S oben
  • S aufgelistet ist eine beschreibende Suffix ("current", "Zustand", und so weiter), so dass Sie müssen die Tabelle nicht oben gespeichert haben, wenn Sie die Metadaten lesen.
  • Ich bin eine optionale eindeutige Nummer
+2

Vielen Dank! Ich werde sehen, ob ich PostSharp-Schließklassen so verhalten kann, wie der C# -Compiler erzeugt! –

+3

Was ist eine dauerhafte temporäre? – SLaks

+7

@SLaks: Das Gegenteil von einem kurzlebigen temporären. Dauerhafte Provisorien sind im Wesentlichen lokale Variablen ohne Namen; Sie haben eine bestimmte Position auf dem Stapel, die für die gesamte Lebensdauer des Stapelrahmens verfügbar ist. Kurzlebige Provisorien werden einfach auf den Stapel geschoben, wenn ihr Speicher benötigt wird, und dann wieder entfernt, wenn sie nicht mehr benötigt werden. Dauerhafte Provisorien lassen sich viel leichter debuggen, können aber die Lebensdauer von Provisorien wesentlich verlängern. Wir generieren dauerhafte Provisorien, wenn Optimierungen deaktiviert sind. –

Verwandte Themen