VS hata ayıklayıcı 'sihirli isimler' hakkında nereden öğrenilir


110

Reflector'ı daha önce kullandıysanız, muhtemelen C # derleyicisinin hata ayıklayıcı tarafından 'özel' gösterimi hak eden türler, yöntemler, alanlar ve yerel değişkenler ürettiğini fark etmişsinizdir. Örneğin, 'CS $' ile başlayan yerel değişkenler kullanıcıya gösterilmez. Anonim yöntemlerin kapatma türleri, otomatik özelliklerin destek alanları vb. İçin başka özel adlandırma kuralları da vardır.

Sorum: bu adlandırma kuralları hakkında nereden bilgi edinebilirim? Bazı belgeleri bilen var mı?

Amacım PostSharp 2.0'ın aynı kuralları kullanmasını sağlamak.

Yanıtlar:


209

Bunlar, derleyicinin belgelenmemiş uygulama ayrıntılarıdır ve herhangi bir zamanda değiştirilebilir. (GÜNCELLEME: GeneratedNames.cs Mevcut ayrıntılar için C # kaynaklarına bakın; aşağıdaki açıklama biraz güncel değildir.)

Ancak, iyi bir adam olduğum için işte bu ayrıntılardan bazıları:

İyileştiricinin kaldırdığı kullanılmayan bir yerel değişkeniniz varsa, bunun için hata ayıklama bilgilerini yine de PDB'ye göndeririz. Soneki __Deleted$bu tür değişkenlere yapıştırdık, böylece hata ayıklayıcı kaynak kodda olduklarını ancak ikili dosyada temsil edilmediklerini bilir.

Derleyici tarafından tahsis edilen geçici değişken yuvalarına, CS $ X $ Y deseniyle adlar verilir; burada X "geçici tür" ve Y, şimdiye kadar ayrılan geçici birimlerin sayısıdır. Geçici türler:

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 ile 264 arasındaki geçici türler, çok boyutlu diziler için ek dizi indeksi depolarıdır.

264'ün üzerindeki geçici türler, bir dizgeyi sabitleyen sabit ifadeyi içeren geçiciler için kullanılır.

Derleyici tarafından oluşturulan özel adlar şunlar için oluşturulur:

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

Büyülü isimler üretme kalıbı: P<N>C__SInerede:

  • P, önbelleğe alınmış temsilciler için CS $ 'dır ve sınıf örneklerini görüntüler, aksi takdirde boştur.
  • N, varsa şeyle ilişkili orijinal addır
  • C, yukarıda listelenen 1'den s'ye kadar olan karakterlerdir
  • S, açıklayıcı bir sonektir ("geçerli", "durum" vb.), Böylece meta verileri okurken yukarıdaki tabloyu ezberlemenize gerek kalmaz.
  • I isteğe bağlı benzersiz bir numaradır

2
Teşekkür ederim! PostSharp kapatma sınıflarının C # derleyicisinin ürettiği kadar iyi davranmasını sağlayıp sağlamayacağımı göreceğim!
Gael Fraiteur

7
@SLaks: Kısa ömürlü bir geçicinin tam tersi. Dayanıklı geçiciler, esasen isimleri olmayan yerel değişkenlerdir; yığın çerçevesinin ömrü boyunca yaşayan yığın üzerinde belirli bir konumu vardır. Kısa ömürlü geçiciler, depolamalarına ihtiyaç duyulduğunda yığına itilir ve daha sonra ihtiyaç kalmadığında açılır. Dayanıklı geçicilerde hata ayıklamak çok daha kolaydır, ancak geçicilerin ömürlerini çok daha uzun sürebilir. Optimizasyonlar kapalıyken dayanıklı geçiciler üretiriz.
Eric Lippert

Kapatma sınıflarına benzer bir konseptim var, ancak parametreleri alan olarak kaldırmak yerine, onları yerel değişkenler olarak aldım. Bu, parametreler için oldukça iyi çalışır, ancak hata ayıklayıcıya "this" in "ldarg.0" değil, dizin 4'e sahip yerel değişken olduğu nasıl söylenir? Sihirli bir isim var mı?
Gael Fraiteur

23
@Eric - bu yanıtı C # 5.0 (async / await) tarafından oluşturulan adlarla güncelleyebilir misiniz? Bazı yeni önekler gördüm :)
Gael Fraiteur
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.