[英]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
呢? 是否取消裝箱值?
似乎有些東西以某種方式將對象拆箱,而沒有我的通知:-(
Object
的Equals
方法是多態的,因此可以被int
類的子類型覆蓋。 Int32.Equals重寫此方法,以在當前對象與其參數之間進行值比較,並且由於一旦取消裝箱后參數相等,則它將返回true。
Int32.Equals
有兩個重載Int32.Equals
bool Equals(object)
和bool Equals(int)
。 bool Equals(object)
重載是object
重寫的object
。 由於t
和aa
是object
引用,因此在示例1和2中將調用此方法。
在示例3中,仍然調用此重載,因為aa
是object
,因此這是唯一有效的重載。
==
運算符是靜態的,並根據其參數類型(在您的示例中都是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`。
由於Int32
的Equals
實現將檢查該值是否相等,並且不關心其他對象引用,因此結果將為“ true”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.