web-dev-qa-db-fra.com

Où en savoir plus sur les «noms magiques» du débogueur VS

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 pour l'utilisateur. Il existe d'autres conventions de dénomination spéciales pour les types de fermeture de méthodes anonymes, les champs de sauvegarde des propriétés automatiques, etc.

Ma question: où en savoir plus sur ces conventions de dénomination? Quelqu'un connaît-il une documentation?

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

108
Gael Fraiteur

Ce sont des détails d'implémentation non documentés du compilateur, et peuvent être modifiés à tout moment. (MISE À JOUR: Voir GeneratedNames.cs dans les sources C # pour les détails actuels; la description ci-dessous est quelque peu dépassée.)

Cependant, puisque je suis un gars sympa, voici certains de ces détails:

Si vous avez une variable locale inutilisée que l'optimiseur supprime, nous émettons quand même des informations de débogage dans la PDB. Nous avons collé le suffixe __Deleted$ sur de telles variables pour que le débogueur sache qu'elles étaient dans le code source mais non représentées dans le binaire.

Les emplacements de variables temporaires alloués par le compilateur sont nommés avec le modèle CS $ X $ Y, où X est le "type temporaire" et Y est le nombre de temporaires 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.  

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

Les types temporaires supérieurs à 264 sont utilisés pour les temporaires impliquant l'instruction fixe fixant une chaîne.

Des noms spéciaux générés par le compilateur 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 délégués mis en cache et les instances de classe d'affichage, sinon vide.
  • N est le nom d'origine associé à la chose, le cas échéant
  • C est le caractère 1 à s indiqué ci-dessus
  • S est un suffixe descriptif ("courant", "état", etc.) afin que vous n'ayez pas à mémoriser le tableau ci-dessus lors de la lecture des métadonnées.
  • I est un numéro unique facultatif
205
Eric Lippert