Object.Equals的IL代码生成

时间:2016-01-02 18:47:02

标签: c# .net

即使类型在运行时解析为Int32,IL也会将其显示为object.equals而不是int32.Equals,如下例所示:

object x = 5;
object y = 5;
Console.WriteLine(x.Equals(y));

但它返回True,这意味着它执行了值相等。我想我的问题不应该是IL instance bool [mscorlib]System.Int32::Equals(int32)

// [18 13 - 18 27]
IL_0001: ldc.i4.5     
IL_0002: box          [mscorlib]System.Int32
IL_0007: stloc.0      // x

// [19 13 - 19 27]
IL_0008: ldc.i4.5     
IL_0009: box          [mscorlib]System.Int32
IL_000e: stloc.1      // y
// [21 13 - 21 46]
IL_000f: ldloc.0      // x
IL_0010: ldloc.1      // y
IL_0011: callvirt     instance bool [mscorlib]System.Object::Equals(object)
IL_0016: call         void [mscorlib]System.Console::WriteLine(bool)
IL_001b: nop          

1 个答案:

答案 0 :(得分:5)

object.Equals方法是虚拟的,并在Int32中被覆盖。 callvirt是一个多态调用 - 它将在调用虚方法之前检查对象的运行时类型,并使用正确的实现。

Int32实现了IEquatable<T>接口,并定义了Equals

的另一个重载
public bool Equals(Int32 obj);

只有当参数和调用它的值的编译时类型为Int32时,编译器才能选择此重载。这里,编译时类型是object,因此编译器只能使用object.Equals(object obj)重载。