เหตุใด 0 จึงเป็นประเภทใน Microsoft Intermediate Language (MSIL)


90

ในรายชื่อ MSIL หลายรายการฉันได้สังเกตสิ่งต่อไปนี้:

System.Nullable`1<!0> etc ...

หรือ

class !0 etc ...

ความหมายของ!0สถานการณ์เหล่านี้คืออะไร?

คำตอบ:


120

นี่คือมุมมองของ decompiler ที่คุณใช้ดูแอสเซมบลี. NET มันเป็นพฤติกรรมของ ildasm.exe ตัวอื่น ๆ เช่น Reflector หรือ ILSpy ทำให้ถูกต้อง โปรแกรมเมอร์ของ Microsoft ที่เขียนมันใช้ทางลัดเขาสร้างสตริงจาก IL ที่แสดงอาร์กิวเมนต์ประเภทตามวิธีที่เข้ารหัสโดยไม่ต้องเขียนโค้ดพิเศษเพื่อค้นหาชื่ออาร์กิวเมนต์ประเภทในข้อมูลเมตา

คุณต้องอ่าน!nเป็นอาร์กิวเมนต์ประเภทที่ n ของประเภททั่วไป โดยที่! 0 หมายถึง "อาร์กิวเมนต์ประเภทแรก",! 1 หมายถึง "อาร์กิวเมนต์ประเภทที่สอง", etcetera สำหรับ Nullable <> คุณรู้ว่า '! 0` หมายถึง' T 'จากบทความ MSDN

!!Tนอกจากนี้คุณยังอาจพบสิ่งที่ต้องการ สองเครื่องหมายอัศเจรีย์บ่งบอกถึงการโต้แย้งประเภทสำหรับทั่วไปวิธีการ เวลานี้ Ildasm.exe ไม่มองขึ้นชื่อประเภทโต้แย้งแทนการใช้!!0มองขึ้นชื่อประเภทโต้แย้งแทนการใช้เหตุใดโปรแกรมเมอร์จึงใช้ทางลัดในประเภททั่วไป แต่ไม่ใช้วิธีการทั่วไปจึงยากที่จะทำวิศวกรรมย้อนกลับ Ildasm เป็นโปรแกรมที่เล่นโวหารได้ดีและเขียนด้วยรูปแบบการเข้ารหัส C ++ ซึ่งแตกต่างจากรหัส C ++ อื่น ๆ ใน. NET ไม่เป็นระเบียบวินัยและไม่เป็นศูนย์ซึ่งเป็นการมอบหมายงานของนักศึกษาฝึกงาน :)

คำต่อท้าย "1 บน" Nullable "เป็นการเข้ารหัสปกติสำหรับชื่อประเภททั่วไปโดยระบุว่าประเภททั่วไปมีอาร์กิวเมนต์ประเภทเดียว กล่าวอีกนัยหนึ่งสำหรับ Nullable <> คุณจะไม่เห็น! 1 ถูกใช้

ให้อ่าน!0ว่า "T" หรือใช้ decompiler ที่ดีกว่า


35

นั่นคือพารามิเตอร์ประเภททั่วไป

พวกเขาเป็นตำแหน่ง

ถอดรหัสรหัสทั่วไปเพื่อดูว่ามีการใช้งานอย่างไร (เปรียบเทียบ IL กับ C #)


5
ถ้าฉันใช้ TryRoslyn ฉันไม่เข้าใจ ... goo.gl/ZZKE38ฉันได้รับ!Tและ!!Tขึ้นอยู่กับว่าพารามิเตอร์ทั่วไปเป็นของคลาสที่มีหรือของวิธีการ ... เช่นเดียวกันถ้าฉันใช้ ildasm
xanatos

@xanatos ไม่เสมอไป ฉันยังเห็นรหัสเหมือนหรือldfld class System.Collections.Generic.Dictionary``2<!0, !1> valuetype System.Collections.Generic.Dictionary``2/Enumerator<!TKey, !TValue>::dictionary call instance void class System.Collections.Generic.Dictionary``2<!TKey, !TValue>::Insert(!0, !1, bool)IL ดิบจะใช้อาร์กิวเมนต์ตำแหน่งเท่านั้นอย่างไรก็ตาม!TKeyนี่เป็นความพยายามที่จะทำให้ IL อ่านได้ง่ายขึ้น อาจจะไม่ได้ผลดีเสมอไป? ข้อมูลจำเพาะของ ECMA จะใช้ตำแหน่ง!0/ !00เช่นกันเสมอ
Luaan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.