为什么MethodBody.GetILAsByteArray在不同的平台上返回不同的数组?

Chr*_*ard 2 .net reflection il cil mscorlib

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

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

我有两台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
Run Code Online (Sandbox Code Playgroud)

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

[0]: 2
[1]: 3
[2]: 40
[3]: 123
[4]: 67
[5]: 0
[6]: 6
[7]: 42
Run Code Online (Sandbox Code Playgroud)

第四个字节是不同的.

现在我知道mscorlib在64位平台上有两种版本.然而,ILDASM揭示了这种方法的IL在风味之间和机器之间是相同的.在x64机器上,我在"任何CPU"和"x86"都定位了上面的代码,但结果是一样的.

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

UPDATE

这是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
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 10

只需编写自己的方法并使用ildasm.exe查看IL内容,即可更好地了解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
Run Code Online (Sandbox Code Playgroud)

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

令牌是程序集清单的元数据表中的索引.当程序集中的代码发生更改并需要添加表时,此类索引将更改.您可以在CLI规范ECMA 335中阅读有关它的更多信息.