Dot-Net-4.0
這是預期的 C# 4.0 元組相等行為嗎?
我看到在 .NET 4.0 的兩個新 Tuple<> 實例之間使用 .Equals 和 == 之間存在不同的行為。如果我在 Tuple<> 中的對像上覆蓋了 Equals 並在 Tuple 上呼叫 .Equals ,則將呼叫 Equals 的覆蓋。如果我在元組上使用 ==,則不會呼叫 Equals 的覆蓋。這是設計使然嗎?有意義嗎?
**編輯:**從答案和評論中,我可以說我不清楚。我知道 Tuple<> 是一個引用類型,對於引用類型 == 將檢查身份(ReferenceEquals)。但是,是否應該 Tuple<> 覆蓋 == 來檢查它包含的對象的相等性?為了一致性,可能不是。
例如,如果我有一個簡單的對象
public class NameAndNumber { public int Number { get; set; } public string Name { get; set; } public override bool Equals(object obj) { if (obj is NameAndNumber) { NameAndNumber other = (NameAndNumber)obj; return Number == other.Number && Name == other.Name; } return false; } }然後我做這樣的事情:
Tuple<NameAndNumber, NameAndNumber> left = new Tuple<NameAndNumber, NameAndNumber>( new NameAndNumber { Name = "one", Number = 1 }, new NameAndNumber { Name = "two", Number = 2 }); Tuple<NameAndNumber, NameAndNumber> right = new Tuple<NameAndNumber, NameAndNumber>( new NameAndNumber { Name = "one", Number = 1 }, new NameAndNumber { Name = "two", Number = 2 }); bool operatorResult = left == right; bool equalsResult = left.Equals(right); Console.Out.WriteLine("operatorResult = {0} equalsResult = {1}", operatorResult, equalsResult);我得到 operatorResult = false equalsResult = true
我應該期待嗎?
我知道 NameAndNumber 上 Equals 的實現並不“正確”,它只是簡化的範常式式碼。
我也嘗試過實現 IEquatable、==、!= 和 GetHashCode。結果相同。
您看到的結果來自設計妥協,元組現在在 F# 和 C# 之間共享。重點是所有元組確實都實現為引用類型,這並不那麼明顯。
Tuples 是否應該進行深或淺相等性檢查的決定已移至兩個介面:
IStructuralComparable,IStructuralEquatable. 請注意,這兩個現在也由 Array 類實現。
對於引用類型: == 執行身份比較,即僅當兩個引用都指向同一個對象時才會返回 true。雖然 Equals() 方法預計會執行值比較,即如果引用指向等價的對象,它將返回 true。
對於 ==沒有被重載的引用類型,它比較兩個引用是否引用同一個對象