เรียนรู้เกี่ยวกับชื่อวิเศษของ VS debugger ได้ที่ไหน


110

หากคุณเคยใช้ตัวสะท้อนแสงคุณอาจสังเกตเห็นว่าคอมไพเลอร์ 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 # สร้างขึ้นหรือไม่!
Gael Fraiteur

7
@SLaks: ตรงกันข้ามกับอายุสั้นชั่วคราว จังหวะที่ทนทานเป็นตัวแปรเฉพาะที่ไม่มีชื่อ พวกเขามีตำแหน่งเฉพาะบนสแต็กที่อยู่ตลอดอายุการใช้งานของสแต็กเฟรม จังหวะสั้น ๆ จะถูกผลักลงบนสแต็กเมื่อจำเป็นต้องใช้ที่เก็บข้อมูลจากนั้นจะเปิดออกเมื่อไม่ต้องการอีกต่อไป จังหวะที่ทนทานนั้นง่ายกว่ามากในการดีบัก แต่สามารถทำให้อายุการใช้งานของจังหวะนานขึ้นได้มาก เราสร้างจังหวะที่ทนทานเมื่อปิดการเพิ่มประสิทธิภาพ
Eric Lippert

ฉันมีแนวคิดคล้ายกับคลาสการปิด แต่แทนที่จะมีพารามิเตอร์ยกเป็นฟิลด์ฉันให้มันเป็นตัวแปรท้องถิ่น สิ่งนี้ใช้ได้ดีกับพารามิเตอร์ แต่จะบอกดีบักเกอร์ได้อย่างไรว่า 'this' ไม่ใช่ 'ldarg.0' แต่เป็นตัวแปรภายในที่มีดัชนี 4 มีชื่อวิเศษหรือไม่?
Gael Fraiteur

23
@Eric - คุณสามารถอัปเดตการตอบกลับนี้ด้วยชื่อที่สร้างโดย C # 5.0 (async / await) ได้หรือไม่ ฉันได้เห็นคำนำหน้าใหม่แล้ว :)
Gael Fraiteur
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.