2

我正在考虑实例方法 Object.Equals(Object)。使用反射,可以将此方法的 IL 作为字节数组获取,如下所示:

var mi = typeof(object).GetMethod("Equals", BindingFlags.Instance | BindingFlags.Public);
var mb = mi.GetMethodBody();
var bytes = mb.GetILAsByteArray();

我有两台 PC:一台是运行 Windows XP 的 32 位计算机,另一台是运行 Windows 7 的 64 位计算机。两台计算机都安装了 .NET Framework 的 4.0.30319 SP1Rel 版本。

在 x86 机器上,生成的数组是:

[0]: 2
[1]: 3
[2]: 40
[3]: 122
[4]: 67
[5]: 0
[6]: 6
[7]: 42

但是,在 x64 机器上,我得到了这个:

[0]: 2
[1]: 3
[2]: 40
[3]: 123
[4]: 67
[5]: 0
[6]: 6
[7]: 42

第四个字节不同。

现在我知道 mscorlib 在 64 位平台上有两种风格。然而,ILDASM 揭示了这种方法的 IL 在不同口味和机器之间是相同的。在 x64 机器上,我将上述代码定位在“Any CPU”和“x86”,但结果是一样的。

所以我的问题是,任何人都可以解释两台机器之间的显着差异吗?

更新

这是 Object.Equals(Object) 的 C# 和 IL:

public virtual bool Equals(object obj)
{
    return RuntimeHelpers.Equals(this, obj);
}

.maxstack  8
IL_0000:  ldarg.0
IL_0001:  ldarg.1
IL_0002:  call bool System.Runtime.CompilerServices.RuntimeHelpers::Equals(object, object)
IL_0007:  ret
4

2 回答 2

10

只需编写您自己的方法并使用 ildasm.exe 查看它,即可更好地了解 IL 内容。在 ildasm 中使用 View + Show bytes 查看字节值,注意它们是十六进制的:

.method public hidebysig newslot virtual 
        instance bool  Equals(object obj) cil managed
// SIG: 20 01 02 1C
{
  // Method begins at RVA 0x2052
  // Code size       8 (0x8)
  .maxstack  8
  IL_0000:  /* 02   |                  */ ldarg.0
  IL_0001:  /* 03   |                  */ ldarg.1
  IL_0002:  /* 28   | (0A)000010       */ call       bool [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::Equals(object,
                                                                                                                           object)
  IL_0007:  /* 2A   |                  */ ret
} // end of method Program::Equals

您现在将看到 IL_0003 处的字节是方法 token的一部分,它的最低有效字节。并注意我得到的价值与你得到的价值有很大的不同。这是因为我刚刚写了一个很小的程序,用很少的代码来测试它,它有一个很小的清单。反汇编器很有帮助,它实际上在元数据表中进行查找并用方法名称替换了标记,而不是只显示标记值。

令牌是程序集清单的元数据表中的索引。当程序集中的代码更改并需要添加到表中时,此类索引将更改。您可以在 CLI 规范ECMA 335中了解更多信息。

于 2013-02-19T13:16:44.527 回答
1

不同的字节是引用的元数据 令牌RuntimeHelpers.Equals()的一部分。重新编译模块时,元数据令牌不能保证稳定。这就是为什么绑定到其他程序集中的符号是按名称而不是元数据令牌发生的。

于 2013-02-19T13:09:56.000 回答