为什么 !0 是 Microsoft 中间语言 (MSIL) 中的一种类型?

Why is !0 a type in Microsoft Intermediate Language (MSIL)?

在许多 MSIL 列表中,我观察到以下内容:

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

class !0 etc ...

在这些情况下,!0 的含义是什么?

这是一个泛型类型参数。

它们是位置性的。

反编译一些通用代码以查看它们的使用方式(比较 IL 与 C#)。

这是您用来查看 .NET 程序集的反编译器的怪癖。这是 ildasm.exe 的行为,其他类似 Reflector 或 ILSpy 的行为是正确的。编写它的 Microsoft 程序员采取了一条捷径,他从 IL 生成一个字符串,该字符串仅按编码方式显示类型参数,而无需编写 extra 代码来查找类型参数名称在元数据中。

您需要阅读 !n 作为泛型类型的第 n 个类型参数。其中 !0 表示 "first type argument",!1 表示 "second type argument",等等。对于 Nullable<>,您知道“!0”表示 MSDN 文章中的 'T'。

你可能还会遇到类似!!T的情况。两个感叹号表示泛型 方法 的类型参数。这一次,ildasm.exe 查找类型参数名称而不是使用 !!0。为什么程序员在泛型类型上走捷径而不在泛型方法上走捷径很难进行逆向工程。 Ildasm 是一个非常古怪的程序,它是用 C++ 编码风格编写的,这与 .NET 中的其他 C++ 代码非常不同。没有纪律严明,这是实习生的作业的可能性非零:)

"Nullable" 上的 `1 后缀是泛型类型名称的正常编码,它表示泛型类型有一个类型参数。换句话说,对于 Nullable<>,您永远不会看到 !1 被使用。

所以只需将 !0 读为 "T"。或者使用更好的反编译器。