OrderBy and Sorting
Vaibhav • September 11, 2025
Sorting is one of the most fundamental operations in programming. Whether you're displaying a list of names
alphabetically, organizing products by price, or ranking scores from highest to lowest, sorting helps make data
meaningful and usable. In LINQ, sorting is handled using the orderby
keyword in
query syntax and the OrderBy
/ OrderByDescending
methods in method syntax. These tools allow you to sort data
based on one or more criteria, in ascending or descending order, with full control over how comparisons are
made.
Sorting with Query Syntax
The orderby
keyword is used in LINQ query syntax to sort elements. By default,
it sorts in ascending order. You can also specify descending
to reverse the
order.
List fruits = new List { "banana", "apple", "cherry", "apricot" };
var sorted = from fruit in fruits
orderby fruit
select fruit;
This query sorts the fruits alphabetically. The result will be: ["apple", "apricot", "banana", "cherry"]
. The orderby
clause compares strings using the default comparer, which is
case-sensitive and culture-aware unless specified otherwise.
Descending Order in Query Syntax
To sort in descending order, simply add the descending
keyword after the orderby
clause.
var reversed = from fruit in fruits
orderby fruit descending
select fruit;
This query returns: ["cherry", "banana", "apricot", "apple"]
. The sorting is
reversed, but still uses the same comparison rules.
Sorting with Method Syntax
Method syntax uses the OrderBy
and OrderByDescending
methods. These are extension methods that take a lambda
expression to specify the sorting key.
var sorted = fruits.OrderBy(f => f);
This is equivalent to the query syntax example above. It sorts the fruits in ascending order based on their string value.
var reversed = fruits.OrderByDescending(f => f);
This sorts the fruits in descending order. The lambda f => f
simply returns the
element itself, which is used as the sorting key.
Sorting by Property
When working with custom objects, you often want to sort by a specific property. Suppose you have a list of products:
class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
}
List products = new List
{
new Product { Name = "Laptop", Price = 999.99m },
new Product { Name = "Tablet", Price = 499.50m },
new Product { Name = "Phone", Price = 799.00m }
};
var sortedByPrice = products.OrderBy(p => p.Price);
This query sorts the products by their price in ascending order. The lambda p => p.Price
extracts the price property from each product.
Sorting by Multiple Criteria
Sometimes you need to sort by more than one property. LINQ supports this using ThenBy
and ThenByDescending
.
var sorted = products
.OrderBy(p => p.Price)
.ThenBy(p => p.Name);
This query first sorts products by price. If two products have the same price, it then sorts them by name. This is useful for creating stable, predictable orderings.
Using orderby
with Multiple Keys
Query syntax also supports multiple sorting keys. You can separate them with commas.
var sorted = from p in products
orderby p.Price, p.Name
select p;
This is equivalent to the method syntax example above. The products are sorted by price, then by name.
Custom Comparers
By default, LINQ uses the standard comparer for the type. For strings, this is culture-sensitive and case-sensitive. You can override this by providing a custom comparer.
var sorted = fruits.OrderBy(f => f, StringComparer.OrdinalIgnoreCase);
This query sorts fruits alphabetically, ignoring case. “Apple” and “apple” are treated as equal. This is useful for user-facing lists where case should not affect order.
Sorting with Computed Keys
You can sort by computed values, such as string length or derived properties.
var sortedByLength = fruits.OrderBy(f => f.Length);
This query sorts fruits by the number of characters in their name. The result will be: ["apple", "banana", "cherry", "apricot"]
- depending on actual lengths.
Sorting with Index
While LINQ doesn’t expose index-based sorting directly, you can simulate it by projecting the index and sorting on it.
var indexed = fruits.Select((fruit, index) => new { fruit, index })
.OrderBy(x => x.index)
.Select(x => x.fruit);
This preserves the original order of the list. It’s useful when you need to sort temporarily and then restore the original sequence.
Sorting and Deferred Execution
Like other LINQ operations, sorting uses deferred execution. The query is not executed until you enumerate the result. This allows you to build complex queries without incurring performance costs until needed.
Note: If you sort a collection and then modify it before enumeration, the changes will affect the result. Always be mindful of when your query is executed.
Sorting and Stability
LINQ’s sorting methods are stable - elements with equal keys retain their original relative order. This is important when chaining multiple sorts or when the original order carries meaning.
Stability means that if two elements compare equal, their order in the result matches their order in the input. This helps avoid unexpected reordering.
Sorting and Performance
Sorting is generally efficient, but it can be costly for large datasets. LINQ uses optimized algorithms under the hood, but you should still be cautious when sorting large collections repeatedly.
If you need to sort a large collection multiple times, consider caching the sorted result
using ToList()
or ToArray()
. This avoids
recomputation and improves performance.
Sorting and Null Values
LINQ handles null
values gracefully. When sorting strings or objects, null
is treated as less than any non-null value. You can customize this behavior
using comparers or conditional logic.
List names = new List { "Alice", null, "Bob" };
var sorted = names.OrderBy(n => n);
This query places null
first, followed by “Alice” and “Bob”. If you want to
exclude null
values, use a where
clause before
sorting.
Sorting and Culture Sensitivity
String sorting is affected by culture. For example, in some cultures, “ä” is considered equal to “a”, while in others it’s distinct. LINQ allows you to specify the comparer to control this behavior.
var sorted = fruits.OrderBy(f => f, StringComparer.CurrentCulture);
This ensures that sorting feels natural to the user’s language and locale. For internal data, prefer Ordinal
or OrdinalIgnoreCase
for consistency.
You can change the current culture using Thread.CurrentThread.CurrentCulture
. This affects all culture-sensitive
operations, including sorting.
Summary
Sorting in LINQ is powerful, flexible, and easy to use. Whether you’re using query syntax or method syntax, you
can sort by single or multiple keys, in ascending or descending order, with full control over comparison rules.
By understanding how OrderBy
, ThenBy
, and
custom comparers work, you can organize your data effectively for display, analysis, or further processing.
Sorting is stable, culture-aware, and integrates seamlessly with other LINQ operations like filtering and
projection.
In the next article, we’ll explore GroupBy Operations - how to categorize data into meaningful groups using LINQ.