ทั้งสองอินเทอร์เฟซใช้สำหรับการเรียงลำดับ (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 ใช้ง่ายกว่า