Back to Blog
C#

C# Array Sort Method Explained with Examples

c# array sort method: Learn how to sort arrays in C# using Array.Sort, custom comparers, and LINQ, including performance and stability tradeoffs.

Array.SortC# SortingLINQ OrderByComparerSorting Performance
Illustration of sorting an array in C# with arrows showing order and code elements.

Sorting an array is one of the most common operations in C#. The c# array sort method, primarily exposed through Array.Sort, provides a fast, in-place sort for single-dimensional arrays. Understanding its overloads and behavior is essential for writing efficient and correct code.

The Array.Sort Method and Its Overloads

The simplest form is Array.Sort(array), which sorts the entire array in ascending order using the default comparer for the element type. For numeric types, this means smallest to largest; for strings, it uses ordinal comparison by default.

int[] numbers = { 5, 2, 8, 1, 9 }; Array.Sort(numbers); // numbers is now { 1, 2, 5, 8, 9 }

Array.Sort has several overloads. You can sort a range of elements with Array.Sort(array, index, length), which is useful when only a portion of the array needs ordering. There are also overloads that accept a custom comparer, which we'll cover shortly.

One important behavior is that Array.Sort performs an in-place sort. It modifies the original array rather than returning a new sorted array. If you need to preserve the original order, you must copy the array first or use a LINQ approach.

Sorting with a Custom Comparer

When the default ordering doesn't match your requirements, you can pass an IComparer<T> implementation to Array.Sort. For example, to sort strings by length instead of alphabetically:

string[] words = { "apple", "kiwi", "banana", "pear" }; Array.Sort(words, (a, b) => a.Length.CompareTo(b.Length)); // Result: { "pear", "kiwi", "apple", "banana" }

Here we use a lambda expression that implements the comparison logic. The lambda receives two elements and returns an integer indicating their relative order. This works because Array.Sort has an overload that accepts a Comparison<T> delegate, which is a simpler alternative to implementing IComparer<T>.

For more complex scenarios, you can define a class that implements IComparer<T> and reuse it across multiple sorts. This is particularly useful when the comparison logic depends on external state or is used in several places.

Sorting in Descending Order

Array.Sort only sorts in ascending order by default. To get descending order, you have two common options. The first is to sort ascending and then call Array.Reverse:

int[] numbers = { 5, 2, 8, 1, 9 }; Array.Sort(numbers); Array.Reverse(numbers); // numbers is now { 9, 8, 5, 2, 1 }

The second approach is to use a custom comparer that reverses the comparison result. For example:

Array.Sort(numbers, (a, b) => b.CompareTo(a));

This works but is slightly less readable. The Array.Reverse approach is clearer and also works with arrays of any type, as long as you have a default sort order.

LINQ OrderBy vs Array.Sort

LINQ's OrderBy method provides a different way to sort arrays. Unlike Array.Sort, OrderBy does not modify the original array. It returns a new IEnumerable<T> that is lazily evaluated. To get a sorted array, you need to call ToArray() or ToList().

int[] numbers = { 5, 2, 8, 1, 9 }; var sorted = numbers.OrderBy(n => n).ToArray(); // sorted is { 1, 2, 5, 8, 9 }; numbers remains unchanged

OrderBy also supports descending order directly with OrderByDescending. It uses a stable sort, meaning that elements with equal keys retain their original relative order. Array.Sort uses an unstable quicksort implementation, so equal elements may be reordered.

For large arrays where in-place sorting is acceptable, Array.Sort is generally faster because it avoids allocating a new collection and uses a more cache-friendly algorithm. However, OrderBy is often more convenient when you need to chain additional LINQ operations or when you don't want to mutate the original data.

Performance and Stability Considerations

The choice between Array.Sort and LINQ OrderBy has practical implications beyond syntax. Array.Sort is an in-place, unstable sort with an average time complexity of O(n log n). It uses the Introspective Sort algorithm, which combines quicksort, heapsort, and insertion sort to avoid worst-case behavior. This makes it a reliable choice for performance-critical code.

LINQ's OrderBy is also O(n log n) but requires additional memory for the new sequence and uses a stable sort. The stability guarantee can be important when sorting by multiple keys. For example, if you first sort by last name and then by first name, a stable sort preserves the last-name order within equal first names. Array.Sort does not guarantee this.

Another performance factor is the comparer. The default comparer for value types is usually optimized, but custom comparers that involve complex calculations can dominate the sorting cost. In such cases, consider precomputing sort keys or using a more efficient comparison strategy.

Sorting Arrays of Custom Types

To sort an array of custom objects, the type must implement IComparable<T> or you must supply a comparer. Without either, Array.Sort will throw an InvalidOperationException because it cannot determine the order.

public class Person { public string Name { get; set; } public int Age { get; set; } } Person[] people = { new Person { Name = "Alice", Age = 30 }, new Person { Name = "Bob", Age = 25 } }; Array.Sort(people, (p1, p2) => p1.Age.CompareTo(p2.Age));

Alternatively, you can implement IComparable<Person> in the class itself, which makes the default Array.Sort work. This is a clean approach when the natural ordering of the type is well-defined.

For more flexible sorting, such as sorting by different properties at different times, a custom IComparer<T> is preferable. You can also use LINQ's OrderBy with a key selector, which is often more readable for one-off sorts.

Common Pitfalls and Edge Cases

Several edge cases can trip up developers when using Array.Sort. First, sorting an array that contains null elements will throw an exception if the comparer tries to call methods on null. You need to handle null explicitly in your comparison logic.

Second, Array.Sort works only on single-dimensional arrays. Multidimensional arrays are not supported; you'll need to flatten them or use a different approach.

Third, the default comparer for strings uses the current culture. This can lead to unexpected ordering in applications that run in different locales. For consistent behavior, use StringComparer.Ordinal as the comparer.

Finally, when sorting a range with Array.Sort(array, index, length), the index and length parameters must be valid; otherwise, an ArgumentOutOfRangeException is thrown. Always validate the range, especially when the array length is dynamic.

Understanding these details helps you avoid common mistakes and write sorting code that behaves predictably across environments. The c# array sort method is straightforward in its basic form, but its overloads and interaction with comparers give you precise control when you need it.