【问题标题】:IL generics - what rules exist for when !T is used vs !0?IL 泛型 - 使用 !T 与 !0 时存在哪些规则?
【发布时间】:2012-07-13 18:06:50
【问题描述】:

我正在编写一个 IL 静态分析工具,但我很难理解管理如何引用泛型类型参数的规则:

获取此 IL(来自 IList<T> interface):

.property instance !T Item(
    int32 index
)
{
    .get instance !0 System.Collections.Generic.IList`1::get_Item(int32)
    .set instance void System.Collections.Generic.IList`1::set_Item(int32, !0)
}

为什么是!0 而不是!T?我认为就 VM 而言它们是等价的,但在保证有名称的情况下使用位置引用似乎很奇怪。

更新:另一个案例,来自 KeyedCollection.ctor:

IL_0037:  newobj instance void class System.Collections.Generic.Dictionary`2<!TKey,!TItem>::'.ctor'(class System.Collections.Generic.IEqualityComparer`1<!0>)
IL_003c:  stfld class System.Collections.Generic.Dictionary`2<!0,!1> class System.Collections.ObjectModel.KeyedCollection`2<!0,!1>::dictionary

【问题讨论】:

  • 我没有看到这个。你确定这不仅仅是你的反汇编程序中的一个错误吗?
  • 嗯,这绝对是反汇编程序(在本例中为 monodis)正在生成的东西。 Mono.Cecil (这似乎更符合书籍元数据)显示,例如:stfld System.Collections.Generic.Dictionary2&lt;TKey,TItem&gt; System.Collections.ObjectModel.KeyedCollection2::dictionary
  • @HansPassant 你用什么来向你展示 IL?

标签: .net generics cil


【解决方案1】:

在Common Language Infrastructure standard、Partition II - Metadata and File Format 第 7.1 条“类型”中指出:

Type ::=        Description
--------        -----------
'!'             Generic parameter in a type definition, accessed by index from 0

如此简短的回答:因为它在规范中。

长答案:这是我的猜测,但基本上,大多数 IL 命令都是基于堆栈的,并且一直使用位置引用作为参数。也就是说,将位置引用用于泛型是有道理的,以便在 IL 中维护通用模式/使用机制。

【讨论】:

  • @svick 不是,它仅用于声明。在元数据中包含名称的目的是保留类型参数的名称,但在使用的地方,它是按位置访问的。
  • 这仍然很令人困惑。 !T 用于属性的声明,但它指的是与 !0 相同的通用参数。我应该假设它们完全可以互换吗?
  • @toshok 不,规范没有说当引用泛型类型参数时可以使用!T。它只是说你可以在声明它们时使用!T。为一个类型创建一个映射来处理这个很容易。
  • 我可能应该在上面包含更多案例。让我编辑添加一些实际的 IL 指令。
  • @toshok 我现在有点明白你的意思了,让我看看能否从规范中获得更多信息。
猜你喜欢
  • 1970-01-01
  • 2012-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多