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

Effective C# 原則 26:實作 IComparable 與 IComparer 建立型別排序關係

     編輯:關於C#

兩大介面:自然順序與自訂順序

  • IComparable:定義型別自然順序(如字串按字典序、數值按大小)。
  • IComparer:提供替代排序順序(如依收入排序客戶)。

IComparable 基礎實作與裝箱效能陷阱

public struct Customer : IComparable {
    private readonly string _name;
    public int CompareTo(object right) { // 非型別安全,需型別檢查、裝箱/拆箱
        if (!(right is Customer)) throw new ArgumentException();
        return _name.CompareTo(((Customer)right)._name);
    }
}

排序 N 筆資料平均比較 N log N 次,每次 3 次裝箱/拆箱,效能損失顯著。

最佳化:隱性介面實作 + 型別安全多載

public struct Customer : IComparable {
    // 隱性實作:僅透過 IComparable 參考存取
    int IComparable.CompareTo(object right) {
        if (!(right is Customer)) throw new ArgumentException();
        return CompareTo((Customer)right);
    }
    // 型別安全公開版本:無裝箱,效能最佳
    public int CompareTo(Customer right) => _name.CompareTo(right._name);
}

消費者呼叫 c1.CompareTo(c2) 直接使用型別安全版本;框架排序透過介面呼叫隱性版本,兩全其美。

多載關係運算子:一致性與便利性

public static bool operator <(Customer left, Customer right) => left.CompareTo(right) < 0;
public static bool operator <=(Customer left, Customer right) => left.CompareTo(right) <= 0;
public static bool operator >(Customer left, Customer right) => left.CompareTo(right) > 0;
public static bool operator >=(Customer left, Customer right) => left.CompareTo(right) >= 0;

確保運算子行為與 CompareTo 完全一致。

IComparer 實作替代排序:巢狀私有類別 + 惰性單例

public struct Customer : IComparable {
    private static RevenueComparer _revComp;
    public static IComparer RevenueCompare => _revComp ??= new RevenueComparer();

    private class RevenueComparer : IComparer {
        int IComparer.Compare(object left, object right) {
            // 型別檢查後比較 _revenue 欄位
            return ((Customer)left)._revenue.CompareTo(((Customer)right)._revenue);
        }
    }
}

使用方式:customerList.Sort(Customer.RevenueCompare);

排序與相等:兩碼子事

  • 排序基於內容(如名稱、金額)。
  • 相等基於身分識別(如主鍵 ID)。
  • Equals 回傳 false 時,CompareTo 可回傳 0,完全合法。

總結

  1. 實作 IComparable 定義自然順序。
  2. 隱性介面實作 + 型別安全公開 CompareTo 兼顧框架相容與效能。
  3. 多載關係運算子委派給 CompareTo。
  4. 需替代順序時,實作 IComparer 並以靜態屬性暴露。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved