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<Person>
{
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<Person> { ... };
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<Person>
{
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<T> = CompareTo(this, other) — natural order
IComparer<T> = Compare(x, y) — custom order(s)
CompareTo/Compare: <0 before, 0 equal, >0 after
Sort() uses IComparable; Sort(comparer) uses IComparer
OrderBy/ThenBy = LINQ, non-mutating