Tại sao! 0 là một loại trong Ngôn ngữ Trung cấp của Microsoft (MSIL)?


88

Trong nhiều danh sách MSIL, tôi đã quan sát thấy những điều sau:

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

hoặc là

class !0 etc ...

Ý nghĩa của !0trong những trường hợp này là gì?

Câu trả lời:


118

Đây là lỗi của trình dịch ngược mà bạn sử dụng để xem một hội đồng .NET. Đó là hành vi của ildasm.exe, những cái khác như Reflector hoặc ILSpy có quyền này. Lập trình viên Microsoft viết nó đã sử dụng một phím tắt, anh ta tạo một chuỗi từ IL mà chỉ hiển thị đối số kiểu theo cách nó được mã hóa, mà không cần viết thêm mã để tra cứu tên đối số kiểu trong siêu dữ liệu.

Bạn cần đọc !nlà đối số kiểu thứ n của kiểu chung. Trong đó! 0 có nghĩa là "đối số loại đầu tiên",! 1 có nghĩa là "đối số loại thứ hai", vân vân. Đối với Nullable <>, bạn biết rằng '! 0` có nghĩa là' T 'từ bài báo MSDN.

Bạn cũng có thể gặp một cái gì đó như !!T. Hai dấu chấm than biểu thị đối số kiểu cho một phương thức chung . Lần này, Ildasm.exe không nhìn lên tên đối số kiểu thay vì sử dụng !!0. Tại sao lập trình viên sử dụng phím tắt trên các kiểu chung chung mà không sử dụng các phương pháp chung thì khó có thể đảo ngược thiết kế. Ildasm là một chương trình khá kỳ quặc và được viết theo phong cách mã hóa C ++ rất khác so với các mã C ++ khác trong .NET. Không có kỷ luật, không có tỷ lệ cược rằng đây là nhiệm vụ của một thực tập sinh :)

Hậu tố `1 trên" Nullable "là một mã hóa thông thường cho các tên kiểu chung, nó cho biết kiểu chung có một đối số kiểu. Nói cách khác, đối với Nullable <> bạn sẽ không bao giờ thấy! 1 được sử dụng.

Vì vậy, chỉ cần đọc !0là "T". Hoặc sử dụng một trình dịch ngược tốt hơn.


35

Đó là một tham số kiểu chung.

Họ có vị trí.

Biên dịch một số mã chung để xem chúng được sử dụng như thế nào (so sánh IL và C #).


5
Nếu tôi sử dụng TryRoslyn, tôi không hiểu ... goo.gl/ZZKE38 Tôi nhận được !T!!T, tùy thuộc vào tham số chung là của lớp chứa hay của phương thức ... Tương tự nếu tôi sử dụng ildasm
xanatos

@xanatos Không phải luôn luôn. Tôi cũng thấy mã giống như ldfld class System.Collections.Generic.Dictionary``2<!0, !1> valuetype System.Collections.Generic.Dictionary``2/Enumerator<!TKey, !TValue>::dictionaryhoặc call instance void class System.Collections.Generic.Dictionary``2<!TKey, !TValue>::Insert(!0, !1, bool). Tuy nhiên, IL thô chỉ sử dụng đối số vị trí - đối số !TKeynày đã là một nỗ lực để làm cho IL dễ đọc hơn. Có lẽ nó không phải lúc nào cũng hoạt động tốt? Đặc tả ECMA luôn sử dụng vị trí !0/ !00cũng như.
Luaan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.