跳到主要内容

IComparable and IComparer

Short, interview-ready summary for sorting and comparison.


Memory hook

"IComparable = type knows how to compare itself; IComparer = separate type compares two objects"


IComparable<T> (default order)

"This type defines its natural order"

public class Person : IComparable&lt;Person&gt;
{
public string Name { get; set; }
public int Age { get; set; }

public int CompareTo(Person? other)
{
if (other is null) return 1;
return Age.CompareTo(other.Age);
}
}

// Usage
var list = new List&lt;Person&gt; { ... };
list.Sort(); // uses IComparable
  • CompareTo(other) — returns < 0 (this before other), 0 (equal), > 0 (this after other)
  • Sort() on List uses IComparable when no comparer is given

IComparer<T> (custom / multiple orders)

"External type defines how to compare two instances"

public class PersonByNameComparer : IComparer&lt;Person&gt;
{
public int Compare(Person? x, Person? y)
{
if (x is null) return y is null ? 0 : -1;
if (y is null) return 1;
return string.Compare(x.Name, y.Name, StringComparison.Ordinal);
}
}

list.Sort(new PersonByNameComparer());
  • Use when you need multiple sort orders or don’t control the type (e.g. can’t implement IComparable)
  • Compare(x, y) — < 0 (x before y), 0, > 0 (x after y)

Comparison<T> delegate

list.Sort((a, b) => a.Age.CompareTo(b.Age));
list.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.Ordinal));
  • Inline comparer without a separate class
  • Same contract: < 0, 0, > 0

OrderBy (LINQ)

var ordered = list.OrderBy((p) => p.Name).ThenBy((p) => p.Age);
var desc = list.OrderByDescending((p) => p.Age);
  • Returns new sequence; does not mutate list
  • ThenBy / ThenByDescending for secondary sort

Interview one-liner

"IComparable means the type defines its natural order (CompareTo). IComparer is a separate type that defines how to compare two instances, so you can have multiple sort orders. Use Comparison delegate for one-off sorts; use OrderBy/ThenBy in LINQ for non-mutating sort."


Cheat sheet

IComparable&lt;T&gt; = CompareTo(this, other) — natural order
IComparer&lt;T&gt; = Compare(x, y) — custom order(s)
CompareTo/Compare: &lt;0 before, 0 equal, &gt;0 after
Sort() uses IComparable; Sort(comparer) uses IComparer
OrderBy/ThenBy = LINQ, non-mutating