2010-03-24 5 views
96

Si vous avez déjà utilisé Reflector, vous avez probablement remarqué que le compilateur C# génère des types, des méthodes, des champs et des variables locales qui méritent un affichage 'spécial' par le débogueur. Par exemple, les variables locales commençant par 'CS $' ne sont pas affichées à l'utilisateur. Il existe d'autres conventions de dénomination spéciales pour les types de fermeture des méthodes anonymes, les champs de sauvegarde des propriétés automatiques, etc.Où apprendre le débogueur VS 'noms magiques'

Ma question: où apprendre ces conventions de nommage? Est-ce que quelqu'un sait quelque documentation?

Mon objectif est de faire en sorte que PostSharp 2.0 utilise les mêmes conventions.

Répondre

190

Il s'agit de détails d'implémentation non documentés du compilateur et susceptibles d'être modifiés à tout moment. (MISE À JOUR: Voir GeneratedNames.cs dans les sources C# pour les détails actuels, la description ci-dessous est un peu hors jour.)

Cependant, depuis que je suis un gars sympa, voici quelques-uns de ces détails:

Si vous avez une variable locale inutilisée que l'optimiseur supprime, nous lui envoyons quand même des informations de débogage dans la PDB. Nous avons bloqué le suffixe __Deleted$ sur de telles variables afin que le débogueur sache qu'il était dans le code source mais pas représenté dans le binaire.

Les emplacements de variables temporaires attribués par le compilateur sont des noms donnés avec le modèle CS $ X $ Y, où X est le "type temporaire" et Y est le nombre de provisoires alloués jusqu'à présent. Les types temporaires sont:

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. 

types temporaires entre 8 et 264 sont des stockages d'index de tableau supplémentaires pour les tableaux multidimensionnels.

Les types temporaires au-dessus de 264 sont utilisés pour les temporaires impliquant l'instruction fixe qui fixe une chaîne.

noms générés par le compilateur spéciaux sont générés pour:

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

Le modèle pour générer des noms magiques est: P<N>C__SI où:

  • P est CS $ pour les instances de classe délégués et affichage mises en cache, vide autrement.
  • N est le nom d'origine associé à la chose, le cas échéant
  • C est le caractère de 1 à s énumérés ci-dessus
  • S est un suffixe descriptif (« courant », « état », et ainsi de suite) de sorte que Vous n'avez pas à mémoriser le tableau ci-dessus en lisant les métadonnées.
  • I est un nombre unique facultatif
+2

Merci! Je vais voir si je peux faire en sorte que les classes de fermeture de PostSharp se comportent aussi bien que ce que le compilateur C# génère! –

+3

Qu'est-ce qu'un temporaire durable? – SLaks

+7

@ SLaks: Le contraire d'un éphémère temporaire. Les temporaries durables sont essentiellement des variables locales sans noms; ils ont un emplacement spécifique sur la pile qui dure toute la vie de la pile. Les temporaires de courte durée sont simplement poussés sur la pile lorsque leur stockage est nécessaire, puis désactivés lorsqu'ils ne sont plus nécessaires. Les temporaries durables sont beaucoup plus faciles à déboguer, mais peuvent rendre les durées de vie des temporaries beaucoup plus longues. Nous générons des temporaires durables lorsque les optimisations sont désactivées. –

Questions connexes