Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

IComparable vs IComparer ใน C#: ความแตกต่าง

ทั้งสองอินเทอร์เฟซใช้สำหรับการเรียงลำดับ (Sorting) และการเปรียบเทียบ (Comparison) แต่มีจุดประสงค์ที่ต่างกัน

IComparable<T> - "ตัวเองรู้จักวิธีเปรียบเทียบตัวเอง"

  • Implement ในคลาสที่ต้องการให้เรียงลำดับได้
  • มีเมธอด CompareTo(T other)
  • ใช้สำหรับ Default/Natural Sorting (เรียงตามคุณสมบัติหลัก)

ตัวอย่าง

public class Person : IComparable<Person>
{
    public string Name { get; set; }
    public int Age { get; set; }
    
    public int CompareTo(Person other)
    {
        if (other == null) return 1;
        return this.Age.CompareTo(other.Age); // เรียงตามอายุ
    }
}

// ใช้งาน
List<Person> people = ...;
people.Sort(); // เรียงตามอายุ (CompareTo)

IComparer<T> - "ภายนอกกำหนดวิธีเปรียบเทียบ"

  • Implement ในคลาสแยกต่างหาก (External Comparer)
  • มีเมธอด Compare(T x, T y)
  • ใช้สำหรับ Custom/Alternative Sorting (เรียงแบบอื่นๆ ได้หลายแบบ)

ตัวอย่าง

// เรียงตามชื่อ
public class NameComparer : IComparer<Person>
{
    public int Compare(Person x, Person y)
    {
        if (x == null && y == null) return 0;
        if (x == null) return -1;
        if (y == null) return 1;
        return string.Compare(x.Name, y.Name);
    }
}

// เรียงตามอายุ descending
public class AgeDescComparer : IComparer<Person>
{
    public int Compare(Person x, Person y)
    {
        if (x == null && y == null) return 0;
        if (x == null) return -1;
        if (y == null) return 1;
        return y.Age.CompareTo(x.Age); // สลับ x y
    }
}

// ใช้งาน
people.Sort(new NameComparer());
people.Sort(new AgeDescComparer());

ตารางเปรียบเทียบ

คุณสมบัติIComparable<T>IComparer<T>
ที่ Implementในคลาสตัวเอง (Intrinsic)ในคลาสภายนอก (Extrinsic)
จำนวนวิธีเรียง1 วิธี (Default)หลายวิธี (หลาย Comparer)
เมธอดCompareTo(T)Compare(T, T)
ใช้กับList.Sort(), Array.Sort()List.Sort(comparer), LINQ OrderBy

LINQ Way (Modern)

var byAge = people.OrderBy(p => p.Age);
var byNameDesc = people.OrderByDescending(p => p.Name);

สรุป: IComparable = เรียงแบบ Default (ในคลาส) | IComparer = เรียงแบบ Custom (นอกคลาส) LINQ ใช้ง่ายกว่า