簡體   English   中英

C#中的Object.Equals澄清?

[英]Object.Equals clarification in C#?

我做了一個簡單的測試:

     object t = 3;
     object aa = 3;
#1   Console.WriteLine(t.Equals(aa));  
#2   Console.WriteLine(t.Equals(3));  
#3   Console.WriteLine(3.Equals(aa));  

所有這些都是真的。(實際上這是我的問題)。

查看object ,這是使用的功能:

 public virtual bool Equals(object obj);

等於是虛擬的。 因此可以將其覆蓋。

但是我不到任何多態行為。 這只是一個純盒裝值。

  • 關於第1行t.Equals(aa)

    引用類型是靜態類型-對象。

    所以我認為它應該調用Object.Equals :這意味着引用是不同的 ,這意味着第一個答案應該是False (在這里我可能錯了)。 這是為什么?

  • 關於第2行t.Equals(3)

    同樣, t's靜態類型是object。 因此Object.Equals正在運行。 為何true

  • 關於第3行3.Equals(aa)

    我相信這是public override bool Equals(object obj); 正在運行,因為靜態類型in t中。 參數類型是對象。 但是為什么會true呢? 是否取消裝箱值?

似乎有些東西以某種方式將對象拆箱,而沒有我的通知:-(

ObjectEquals方法是多態的,因此可以被int類的子類型覆蓋。 Int32.Equals重寫此方法,以在當前對象與其參數之間進行值比較,並且由於一旦取消裝箱后參數相等,則它將返回true。

Int32.Equals有兩個重載Int32.Equals bool Equals(object)bool Equals(int) bool Equals(object)重載是object重寫的object 由於taaobject引用,因此在示例1和2中將調用此方法。

在示例3中,仍然調用此重載,因為aaobject ,因此這是唯一有效的重載。

==運算符是靜態的,並根據其參數類型(在您的示例中都是object進行靜態解析。 object==運算符將比較引用,在這種情況下,對於兩個單獨的裝箱的整數將返回false。

虛擬方法Object.Equals被調用,但是由於虛擬方法的工作方式,它改為調用Int32.Equals方法,該方法比較int值,而不是引用。

虛擬方法在運行時綁定。 也就是說,他們在運行時而不是在編譯時選擇適當的方法。 在這種情況下, Object.Equals是編譯后的代碼中的內容,但是由於您要比較int ,因此它在運行時選擇Int32.Equals 這可以通過使用稱為v表的表來完成(以防您想了解更多信息)。

請記住, Equals應該這樣,如果您確實想要引用相等,則可以使用ReferenceEquals

請注意,這與拳擊沒有任何關系。 例如,使用string或自定義類,您將獲得相同的行為。

正如您在問題中所寫,以下聲明將全部通過

[Test] 
public void EqualityOnInts()
{
    object a = 1;
    object b = 1;

    Assert.AreEqual(a, b);
    Assert.IsTrue(1.Equals(a));
    Assert.IsTrue(b.Equals(1));
}

如果你實例化a你創建一個新integer對象與值1調用Equals上方法a會導致調用Equals的方法Int32 另外,如果執行a.GetType() it will return Int32`。

由於Int32Equals實現將檢查該值是否相等,並且不關心其他對象引用,因此結果將為“ true”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM