Де дізнатися про відладчик VS "магічні імена"


110

Якщо ви коли-небудь використовували Reflector, ви, мабуть, помітили, що компілятор C # генерує типи, методи, поля та локальні змінні, які заслуговують на "спеціальний" показ налагоджувачем. Наприклад, локальні змінні, що починаються з "CS $", не відображаються користувачеві. Існують й інші спеціальні умови іменування для закриття типів анонімних методів, резервного поля автоматичних властивостей тощо.

Моє запитання: де дізнатися про ці умови іменування? Хтось знає про якусь документацію?

Моя мета - змусити PostSharp 2.0 використовувати ті самі умови.

Відповіді:


209

Це недокументовані деталі реалізації компілятора і можуть бути змінені в будь-який час. (ОНОВЛЕННЯ. GeneratedNames.cs Поточні деталі див. У джерелах C #; опис, наведений нижче, є дещо застарілим.)

Однак, оскільки я хороший хлопець, ось деякі з цих деталей:

Якщо у вас є невикористана локальна змінна, яку оптимізатор видаляє, ми все одно передаємо інформацію про налагодження для неї в PDB. Ми приклеїли суфікс __Deleted$до таких змінних, щоб налагоджувач знав, що вони були у вихідному коді, але не представлені у двійковій.

Тимчасові слоти змінної, виділені компілятором, отримують імена з шаблоном CS $ X $ Y, де X - "тимчасовий вид" і Y - кількість тимчасових виділених досі. Тимчасовими видами є:

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.  

Тимчасові типи між 8 і 264 - це додаткові сховища індексів масивів для багатовимірних масивів.

Тимчасові типи вище 264 використовуються для часописів, що включають фіксований оператор, що фіксує рядок.

Спеціальні імена, створені компілятором, створюються для:

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

Шаблон генерації магічних імен такий: P<N>C__SIде:

  • P - CS $ для кешованих делегатів і примірників класу відображення, в іншому випадку порожнє.
  • N - це оригінальна назва, пов'язана з річчю, якщо така є
  • C - символи від 1 до s, перелічені вище
  • S - це описовий суфікс ("поточний", "стан" тощо), щоб вам не довелося запам’ятовувати вищезгадану таблицю під час читання метаданих.
  • Я - необов'язковий унікальний номер

2
Дякую! Я побачу, чи можу я змусити класи закриття PostSharp вести себе так само добре, як те, що створює компілятор C #!
Гаель Фрайтер

7
@SLaks: протилежність короткочасного тимчасового. Стійкі часові емісії - це по суті локальні змінні без імен; вони мають певне місце розташування на стеку, яке живе протягом усього часу кадру стека. Недовговічні часописи просто натискають на стек, коли потрібно їх зберігання, а потім вискакують, коли це вже не потрібно. Міцні часописи набагато простіше налагоджувати, але вони можуть зробити життя тимчасових істотно довше. Ми створюємо довговічні часописи, коли оптимізація вимкнена.
Ерік Ліпперт

У мене є концепція, подібна до класів закриття, але замість розміщених параметрів як полів, я маю їх як локальні змінні. Це працює досить добре для параметрів, але як сказати налагоджувачу, що "це" не "ldarg.0", а локальна змінна з індексом 4? Чи є якесь чарівне ім’я?
Gael Fraiteur

23
@Eric - чи можете ви оновити цю відповідь іменами, створеними C # 5.0 (async / wait)? Я бачив нові приставки :)
Gael Fraiteur
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.