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

.NET 介面深度剖析:IComparable 與 IComparer 的比較與排序模式

     編輯:關於C#

核心概念:能力認證與策略分離

介面是對型別能力的標準化認證。IComparable 表示「我自己知道如何與同類比較」;IComparer 表示「我知道如何比較兩個物件」。這是策略模式在 .NET 框架中的經典應用:

  • 內建比較:型別實作 IComparable,預設排序行為
  • 外部比較器:實作 IComparer,支援多種排序規則、降序、多欄位排序等

IComparable / IComparable<T>

public interface IComparable { int CompareTo(object obj); }
public interface IComparable { int CompareTo(T other); }

回傳值:負數(小於)、零(等於)、正數(大於)。實作範例:

public class Student : IComparable
{
    public string Name { get; set; }
    public Scores Scores { get; set; }

    public int CompareTo(Student other)
    {
        if (other == null) return 1;
        return Name.CompareTo(other.Name); // 依姓名預設排序
    }
}

// 使用
var students = new[] { new Student("Michale"), new Student("Jack"), ... };
Array.Sort(students); // 自動呼叫 CompareTo

IComparer / IComparer<T>:專業比較器

public interface IComparer { int Compare(object x, object y); }
public interface IComparer { int Compare(T x, T y); }

優勢:

  • 將比較邏輯從型別中抽離,符合單一職責原則
  • 可攜帶參數(如排序欄位、升降序),靈活復用
  • 同一型別可擁有多種比較器
public class StudentComparer : IComparer
{
    private readonly SubjectEnum _subject;
    private readonly bool _descending;

    public StudentComparer(SubjectEnum subject, bool descending)
    {
        _subject = subject;
        _descending = descending;
    }

    public int Compare(Student x, Student y)
    {
        if (x == null && y == null) return 0;
        if (x == null) return -1;
        if (y == null) return 1;

        int result = x.Scores[_subject].CompareTo(y.Scores[_subject]);
        return _descending ? -result : result;
    }
}

// 使用:依總分降序
Array.Sort(students, new StudentComparer(SubjectEnum.Total, true));

進階:Comparison<T> 委派與 LINQ OrderBy


// 匿名委派 / Lambda 簡潔寫法
Array.Sort(students, (x, y) => x.Scores[SubjectEnum.Math].CompareTo(y.Scores[SubjectEnum.Math]));

// LINQ 風格(回傳新序列,不修改原陣列)
var sorted = students.OrderBy(s => s.Scores[SubjectEnum.English])
                     .ThenByDescending(s => s.Scores[SubjectEnum.Math]);

Comparison<T> 是 Func<T,T,int> 的別名,Array.Sort 與 List<T>.Sort 皆有多載接受它。

實作檢查清單

介面適用場景注意事項
IComparable<T>型別有自然預設排序(如數值、日期、字串、編號)實作需滿足傳遞性、對稱性、自反性;處理 null 語意
IComparer<T>多種排序規則、外部型別、需參數化比較建議實作 IComparer<T> 而非非泛型版本;可序列化
Comparison<T>一次性、簡單比較邏輯無法攜帶狀態,複雜邏輯改用 IComparer

總結

掌握 IComparable(內建能力)與 IComparer(外部策略)的分工,能寫出既符合框架慣例又靈活擴充的排序程式碼。這也是介面導向設計「程式介面而非實作」的典範。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved