C# tutorials > Core C# Fundamentals > Data Structures and Collections > How do you sort a Collection in C# (`List<T>.Sort()`, LINQ `OrderBy`)?
How do you sort a Collection in C# (`List<T>.Sort()`, LINQ `OrderBy`)?
Sorting collections is a fundamental operation in C#. This tutorial explores two primary methods: the List<T>.Sort()
method and the LINQ OrderBy
(and OrderByDescending
) methods. We will cover how to use each method, their differences, performance considerations, and when to use each effectively.
Sorting with `List.Sort()`
The Key characteristics:List<T>.Sort()
method sorts the elements of the entire List<T>
in place. This means it modifies the original list directly. By default, it sorts in ascending order using the default comparer for the type T
. In the example above, it sorts a list of integers and a list of strings alphabetically.
using System;
using System.Collections.Generic;
public class Example
{
public static void Main(string[] args)
{
List<int> numbers = new List<int> { 5, 2, 8, 1, 9 };
Console.WriteLine("Original List: " + string.Join(", ", numbers));
numbers.Sort(); // Sorts the list in place (ascending order)
Console.WriteLine("Sorted List (List.Sort()): " + string.Join(", ", numbers));
List<string> names = new List<string> { "Charlie", "Alice", "Bob" };
names.Sort();
Console.WriteLine("Sorted Names (List.Sort()): " + string.Join(", ", names));
}
}
Sorting with LINQ `OrderBy`
LINQ's Key characteristics:OrderBy
method provides a more flexible way to sort collections. It returns a new sorted IEnumerable<T>
without modifying the original collection. You can also use OrderByDescending
to sort in descending order.
IEnumerable<T>
.
using System;
using System.Collections.Generic;
using System.Linq;
public class Example
{
public static void Main(string[] args)
{
List<int> numbers = new List<int> { 5, 2, 8, 1, 9 };
Console.WriteLine("Original List: " + string.Join(", ", numbers));
IEnumerable<int> sortedNumbers = numbers.OrderBy(x => x); // Sorts using LINQ
Console.WriteLine("Sorted List (LINQ OrderBy): " + string.Join(", ", sortedNumbers));
List<string> names = new List<string> { "Charlie", "Alice", "Bob" };
IEnumerable<string> sortedNames = names.OrderBy(name => name);
Console.WriteLine("Sorted Names (LINQ OrderBy): " + string.Join(", ", sortedNames));
IEnumerable<int> descendingNumbers = numbers.OrderByDescending(x => x);
Console.WriteLine("Sorted List (LINQ OrderByDescending): " + string.Join(", ", descendingNumbers));
}
}
Sorting with Custom Comparer
Both List<T>.Sort()
and LINQ OrderBy
allow you to specify a custom comparer to define how elements should be compared. For List<T>.Sort()
, you can implement the IComparer<T>
interface. With LINQ, you typically use a lambda expression to define the sorting criteria inline.
using System;
using System.Collections.Generic;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class AgeComparer : IComparer<Person>
{
public int Compare(Person x, Person y)
{
return x.Age.CompareTo(y.Age);
}
}
public class Example
{
public static void Main(string[] args)
{
List<Person> people = new List<Person>
{
new Person { Name = "Charlie", Age = 30 },
new Person { Name = "Alice", Age = 25 },
new Person { Name = "Bob", Age = 35 }
};
Console.WriteLine("Original List:");
foreach (var person in people) { Console.WriteLine($"{person.Name}: {person.Age}"); }
people.Sort(new AgeComparer());
Console.WriteLine("\nSorted List by Age (List.Sort with IComparer):");
foreach (var person in people) { Console.WriteLine($"{person.Name}: {person.Age}"); }
//Using LINQ OrderBy with custom sorting
people.Sort((p1, p2) => p1.Name.CompareTo(p2.Name)); //Sort by Name using lambda
Console.WriteLine("\nSorted List by Name (List.Sort with Lambda):");
foreach (var person in people) { Console.WriteLine($"{person.Name}: {person.Age}"); }
}
}
Sorting with Custom Comparer using LINQ
LINQ's OrderBy
can directly take a lambda expression that defines the property to sort by. This approach is concise and readable for simple sorting criteria.
using System;
using System.Collections.Generic;
using System.Linq;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class Example
{
public static void Main(string[] args)
{
List<Person> people = new List<Person>
{
new Person { Name = "Charlie", Age = 30 },
new Person { Name = "Alice", Age = 25 },
new Person { Name = "Bob", Age = 35 }
};
Console.WriteLine("Original List:");
foreach (var person in people) { Console.WriteLine($"{person.Name}: {person.Age}"); }
IEnumerable<Person> sortedPeopleByAge = people.OrderBy(person => person.Age);
Console.WriteLine("\nSorted List by Age (LINQ OrderBy):");
foreach (var person in sortedPeopleByAge) { Console.WriteLine($"{person.Name}: {person.Age}"); }
IEnumerable<Person> sortedPeopleByName = people.OrderBy(person => person.Name);
Console.WriteLine("\nSorted List by Name (LINQ OrderBy):");
foreach (var person in sortedPeopleByName) { Console.WriteLine($"{person.Name}: {person.Age}"); }
}
}
Concepts Behind the Snippet
The core concept behind sorting algorithms is comparing elements and rearranging them based on a defined order. Both List<T>.Sort()
and LINQ OrderBy
rely on comparers to determine the order of elements. List<T>.Sort()
typically uses the IComparable implementation of the objects being sorted unless an IComparer implementation is provided.
Real-Life Use Case Section
Scenario: Sorting a list of products by price or name in an e-commerce application. Imagine you have a list of product objects, each with properties like Example:Name
, Price
, and Rating
. You want to allow users to sort the products based on these criteria.
OrderBy
or OrderByDescending
.OrderBy
.List<T>.Sort()
would be suitable if you need to update the original list in place, while OrderBy
is preferable if you want to display a sorted view of the data without modifying the underlying product list.
Best Practices
List<T>.Sort()
. If you need a new sorted collection, use LINQ OrderBy
.IComparer<T>
or use a lambda expression.List<T>.Sort()
is generally faster for in-place sorting. LINQ OrderBy
has the overhead of creating a new collection.List
or array using ToList()
or ToArray()
to avoid re-evaluation.
Interview Tip
Be prepared to discuss the differences between A good answer would discuss in-place sorting versus creating a new collection, as well as the use of List<T>.Sort()
and LINQ OrderBy
, including their impact on the original collection and their performance characteristics. Also, be ready to explain how to implement custom comparers for more complex sorting scenarios.IComparer
and lambda expressions.
When to use them
List<T>.Sort()
: Use when you need to sort the original list directly and don't need to preserve the original order. It's also generally faster for in-place sorting.OrderBy
: Use when you need to create a new sorted collection without modifying the original list. It's also more flexible for complex sorting scenarios and can be chained with other LINQ methods. Use it when you want immutability.
Memory footprint
List<T>.Sort()
: Has a lower memory footprint because it sorts the list in place.OrderBy
: Has a higher memory footprint because it creates a new collection to store the sorted result.
Alternatives
While List<T>.Sort()
and LINQ OrderBy
are the most common methods for sorting, other alternatives exist:
List<T>.Sort()
but for arrays.
Pros of `List.Sort()`
OrderBy
.
Cons of `List.Sort()`
OrderBy
for complex sorting scenarios.
Pros of LINQ `OrderBy`
Cons of LINQ `OrderBy`
List<T>.Sort()
due to the overhead of creating a new collection.
FAQ
-
What's the difference between `List
.Sort()` and LINQ `OrderBy`?
List<T>.Sort()
sorts the list in-place, modifying the original list directly, and is generally faster. LINQOrderBy
returns a new sortedIEnumerable<T>
, leaving the original list unchanged, and provides more flexibility for complex sorting scenarios. -
How do I sort a list of objects by a specific property?
You can use either
List<T>.Sort()
with a customIComparer<T>
or LINQOrderBy
with a lambda expression that specifies the property to sort by. -
Can I sort in descending order?
Yes, you can use
OrderByDescending
in LINQ to sort in descending order. ForList<T>.Sort()
, you can implement a customIComparer<T>
that compares elements in reverse order. -
Is it possible to sort a list of objects by multiple properties?
Yes, using LINQ's
ThenBy
(andThenByDescending
) methods which allows you to specify secondary sorting criteria after the initialOrderBy
orOrderByDescending
. Alternatively, you can create a customIComparer<T>
that compares objects based on multiple properties.