Multiple OrderBy
ID |
csharp.multiple_orderby |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
CSharp |
Tags |
linq, reliability |
Description
Reports a LINQ chain that calls OrderBy (or OrderByDescending) twice in succession.
The second call re-sorts the sequence from scratch and discards the first ordering, so
only the last criterion is actually applied. A multi-key sort is expressed with ThenBy /
ThenByDescending.
Rationale
OrderBy returns a sequence whose elements are arranged by a single key. Calling
OrderBy again on the result repeats that — every element is repositioned by the new
key alone, with no memory of the previous one. The intent of "sort by A and then by B"
is what ThenBy exists for; using OrderBy.OrderBy silently produces a different
result.
using System.Linq;
using System.Collections.Generic;
public class Sorter
{
public IEnumerable<Person> Bad(IEnumerable<Person> people) =>
people.OrderBy(p => p.LastName) // FLAW — sort lost by the next OrderBy
.OrderBy(p => p.FirstName);
public IEnumerable<Person> Good(IEnumerable<Person> people) =>
people.OrderBy(p => p.LastName) // OK — secondary sort via ThenBy
.ThenBy(p => p.FirstName);
}
Remediation
Replace the second (and any subsequent) OrderBy in the chain with ThenBy, and
OrderByDescending with ThenByDescending. The primary OrderBy stays as the first
call.