2016-01-02 40 views
0

即使在運行時解析到的Int32類型,IL表明它叫的Object.Equals代替int32.Equals,像這樣的例子:IL代碼生成的Object.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

「解析爲Int32 _at runtime_」的類型 - 這是關鍵點。 –

回答

5

object.Equals方法是虛擬的,並在Int32被覆蓋。 callvirt是一個多態調用 - 它將在調用虛方法之前檢查對象的運行時類型,並使用正確的實現。

Int32實現IEquatable<T>接口和定義的Equals

public bool Equals(Int32 obj); 

編譯器另一個重載可以選擇此重載僅在參數和值兩者的編譯時類型,它被稱爲是上Int32。在此,編譯時類型爲object,因此編譯器只能使用object.Equals(object obj)過載。

+0

當然,如果兩個比較在編譯時是「int」(聲明類型),那麼最好做的就是在這兩個整數之間說'=='。這轉到了編譯器熟知的C#預定義重載'bool operator ==(int,int)',編譯器轉換爲堆棧中兩個數字的簡單相等檢查。所以你很少直接調用'int.Equals(int)'。 –

+0

謝謝。我錯誤地解釋了IL。 – Joe