Summary#
list.Sort((a, b) => …) orders the list you are holding by a rule you write as a comparison — C#'s
Sort(Comparison<T>). Reach for it when the order has no single key to hand to OrderBy: version numbers
(1.10 comes after 1.9, which no string order says), a rank with exceptions, a "this field, unless…" rule.
When the order is a key, OrderBy(x => x.Field) says it more plainly — see List OrderBy (in-memory).
Signature#
list.Sort((a, b) => comparison); // order the list by your comparison → nothing
list.Sort(cmp); // or any Func<T, T, int> valueDescription#
The comparison takes two elements and answers an int:
| It answers | Meaning |
|---|---|
| negative | a goes before b |
0 | they tie — and keep the order they already had |
| positive | b goes before a |
So (a, b) => a - b is ascending and (a, b) => b - a is descending. The comparison may read captured
locals, call your own functions, and compare fields of class elements; it may also be a Func<T, T, int>
held in a local or passed in as a parameter.
It is stable. Two elements the comparison calls equal keep their written order. That is not C#'s
List<T>.Sort, which is an unstable introsort, but it is what Sort() and OrderBy already promise here,
so all three sorting verbs follow one rule and the answer is the same on the server and in the browser.
Like Sort(), it changes the list in place and answers nothing: every other holder of the same list sees
the new order. OrderBy is the copying counterpart.
A one-parameter lambda is refused — that is a sort key, and the refusal names OrderBy. IComparer<T>
has no spelling here; pass a comparison instead.
Examples#
int CompareVersion(string a, string b) {
var pa = a.Split('.');
var pb = b.Split('.');
for (int i = 0; i < 2; i++) {
var d = int.Parse(pa[i]) - int.Parse(pb[i]);
if (d != 0) return d;
}
return 0;
}
List<string> NewestFirst(List<string> versions) {
var sorted = versions.ToList(); // a copy, so the caller's list keeps its order
sorted.Sort((a, b) => CompareVersion(b, a)); // 2.0, 1.10, 1.9, 1.2
return sorted;
}class Task { public string Title = ""; public int Priority; }
void ByPriority(List<Task> tasks) {
// Equal priorities stay in the order they were added — the sort is stable.
tasks.Sort((x, y) => x.Priority - y.Priority);
}See also#
- List Sort, Reverse and RemoveAt (in place) —
Sort()by the elements' natural order,Reverse(),RemoveAt(i) - List OrderBy (in-memory) — the copying counterpart, sorting by a key
- OrderBy / ThenBy — ordering a query, which runs in the database