How to sort with LINQ OrderBy in C#
The LINQ OrderBy() and OrderByDescending() methods sort a sequence without modifying the original collection. They return a new IOrderedEnumerable<T> that you can chain with ThenBy() for multi-key sorting.
Unlike List<T>.Sort(), which mutates the list in place, LINQ ordering always produces a new sequence.
OrderBy() uses a stable sort — elements with equal keys preserve their original order.
Basic Ascending Sort
C# Example Code
var numbers = new List<int> { 5, 1, 8, 3, 9, 2 };
var sorted = numbers.OrderBy(n => n).ToList();
Console.WriteLine(string.Join(", ", sorted));
// Output: 1, 2, 3, 5, 8, 9Descending Sort
C# Example Code
var numbers = new List<int> { 5, 1, 8, 3, 9, 2 };
var descending = numbers.OrderByDescending(n => n).ToList();
Console.WriteLine(string.Join(", ", descending));
// Output: 9, 8, 5, 3, 2, 1Sort a List of Strings
C# Example Code
var fruits = new List<string> { "banana", "apple", "cherry", "date" };
// Alphabetical (A–Z)
var az = fruits.OrderBy(f => f).ToList();
Console.WriteLine(string.Join(", ", az));
// Output: apple, banana, cherry, date
// Reverse alphabetical (Z–A)
var za = fruits.OrderByDescending(f => f).ToList();
Console.WriteLine(string.Join(", ", za));
// Output: date, cherry, banana, appleSort Objects by Property
C# Example Code
var people = new List<Person>
{
new Person("Charlie", 35),
new Person("Alice", 30),
new Person("Bob", 25),
new Person("Dave", 25)
};
// Sort by age ascending
var byAge = people.OrderBy(p => p.Age).ToList();
foreach (var p in byAge)
Console.WriteLine($"{p.Name}: {p.Age}");
// Output:
// Bob: 25
// Dave: 25
// Alice: 30
// Charlie: 35
record Person(string Name, int Age);Multi-Key Sort with ThenBy
C# Example Code
var people = new List<Person>
{
new Person("Charlie", 35),
new Person("Alice", 30),
new Person("Bob", 25),
new Person("Dave", 25)
};
// Primary: age ascending; secondary: name ascending
var sorted = people
.OrderBy(p => p.Age)
.ThenBy(p => p.Name)
.ToList();
foreach (var p in sorted)
Console.WriteLine($"{p.Name}: {p.Age}");
// Output:
// Bob: 25 ← age 25, alphabetically first
// Dave: 25 ← age 25, alphabetically second
// Alice: 30
// Charlie: 35ThenByDescending
C# Example Code
var employees = new List<Employee>
{
new Employee("Alice", "Engineering", 95000),
new Employee("Bob", "Marketing", 72000),
new Employee("Carol", "Engineering", 88000),
new Employee("Dave", "Marketing", 85000)
};
// Sort by department A–Z, then by salary Z–A within department
var sorted = employees
.OrderBy(e => e.Department)
.ThenByDescending(e => e.Salary)
.ToList();
foreach (var e in sorted)
Console.WriteLine($"{e.Department} | {e.Name} | {e.Salary:C0}");
// Output:
// Engineering | Alice | $95,000
// Engineering | Carol | $88,000
// Marketing | Dave | $85,000
// Marketing | Bob | $72,000
record Employee(string Name, string Department, decimal Salary);Sort Strings by Length
C# Example Code
var words = new List<string> { "banana", "kiwi", "apple", "fig", "cherry" };
// Sort by length, then alphabetically within same length
var sorted = words
.OrderBy(w => w.Length)
.ThenBy(w => w)
.ToList();
Console.WriteLine(string.Join(", ", sorted));
// Output: fig, kiwi, apple, banana, cherryMethod Syntax vs Query Syntax
C# Example Code
var numbers = new List<int> { 5, 1, 8, 3, 9, 2 };
// Method syntax
var methodResult = numbers.OrderBy(n => n).ToList();
// Query syntax
var queryResult = (from n in numbers
orderby n ascending
select n).ToList();
// Multi-key in query syntax
var people = new List<Person> { /* ... */ };
var queryMulti = (from p in people
orderby p.Age ascending, p.Name descending
select p).ToList();OrderBy vs List.Sort — Key Differences
OrderBy() (LINQ) | List<T>.Sort() | |
|---|---|---|
| Source | Any IEnumerable<T> | List<T> only |
| Mutates original | No — returns new sequence | Yes — sorts in place |
| Return type | IOrderedEnumerable<T> | void |
| Stable sort | Yes | Yes (.NET 5+) |
| Multi-key | ThenBy() / ThenByDescending() | Custom IComparer<T> |
| Use case | Functional pipeline | In-place mutation |
C# Example Code
var numbers = new List<int> { 5, 1, 8, 3, 9, 2 };
// LINQ — original list unchanged
var sorted = numbers.OrderBy(n => n).ToList();
Console.WriteLine("Original: " + string.Join(", ", numbers)); // 5, 1, 8, 3, 9, 2
Console.WriteLine("Sorted: " + string.Join(", ", sorted)); // 1, 2, 3, 5, 8, 9
// List.Sort — mutates original
numbers.Sort();
Console.WriteLine("After Sort: " + string.Join(", ", numbers)); // 1, 2, 3, 5, 8, 9