Dot-Net-4.0

這是預期的 C# 4.0 元組相等行為嗎?

  • October 11, 2009

我看到在 .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&lt;NameAndNumber, NameAndNumber&gt; left = new Tuple&lt;NameAndNumber, NameAndNumber&gt;(
     new NameAndNumber { Name = "one", Number = 1 }, 
     new NameAndNumber { Name = "two", Number = 2 });
Tuple&lt;NameAndNumber, NameAndNumber&gt; right = new Tuple&lt;NameAndNumber, NameAndNumber&gt;(
     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。

對於 ==沒有被重載的引用類型,它比較兩個引用是否引用同一個對象

引用自:https://stackoverflow.com/questions/1483059