首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 呼叫 Remove 失效分析(二):EqualityComparer.Default 機制與兩種修正方案

     編輯:關於C語言

根因:List<T> 使用 EqualityComparer.Default

SDK 文件:This method determines equality using the default equality comparer EqualityComparer.Default for T

EqualityComparer.Default 判等邏輯

  1. 若 T 實作 IEquatable<T> → 使用其 Equals
  2. 否則 → 使用 Object.Equals / Object.GetHashCode (參考比較)

問題重現


IList products = new List();
products.Add(GetProduct("1412"));      // 新實例 A
products.Remove(GetProduct("1412"));   // 新實例 B (不同參考)
// 參考不相等 → Remove 失效 → Count 仍為 1

GetProduct 每次回傳新實例,導致「不死物件」。

兩種修正方案

方案一:實作 IEquatable<T>


public class Product : IEquatable
{
    public string ID { get; private set; }
    public Product(string id) { ID = id; }
    
    public bool Equals(Product other)
    {
        return other != null && this.ID == other.ID;
    }
    public override bool Equals(object obj) => Equals(obj as Product);
    public override int GetHashCode() => ID.GetHashCode();
}

方案二:覆寫 Equals/GetHashCode (不實作介面)


public class Product
{
    public string ID { get; private set; }
    public Product(string id) { ID = id; }
    
    public override bool Equals(object obj)
    {
        return obj is Product other && this.ID == other.ID;
    }
    public override int GetHashCode() => ID.GetHashCode();
}

最佳實踐建議

  • 實體類別**必須**覆寫 Equals/GetHashCode 或實作 IEquatable<T>
  • 判等依據:業務鍵 (如 ID),而非參考
  • GetHashCode 必須與 Equals 一致 (相等物件 HashCode 必相同)
  • 避免為了集合移除而引入物件快取 (過度設計)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved