Sorting By Functions in C#

Sometimes we’ll want to sort a collection by something other than its natural order. For example, suppose we wanted to sort strings by their length instead of alphabetically. Here’s an example of custom sorts in C#.

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        List<string> fruits = new List<string> { "peach", "banana", "kiwi" };

        // We implement a comparison function for string lengths.
        Comparison<string> lenCmp = (a, b) => a.Length.CompareTo(b.Length);

        // Now we can call Sort with this custom comparison function to sort fruits by name length.
        fruits.Sort(lenCmp);
        Console.WriteLine(string.Join(", ", fruits));

        // We can use the same technique to sort a list of values that aren't built-in types.
        class Person
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }

        List<Person> people = new List<Person>
        {
            new Person { Name = "Jax", Age = 37 },
            new Person { Name = "TJ", Age = 25 },
            new Person { Name = "Alex", Age = 72 }
        };

        // Sort people by age using a lambda expression.
        people.Sort((a, b) => a.Age.CompareTo(b.Age));
        Console.WriteLine(string.Join(", ", people.Select(p => $"{p.Name} ({p.Age})")));
    }
}

To run the program, save it as SortingByFunctions.cs and use the C# compiler:

$ csc SortingByFunctions.cs
$ mono SortingByFunctions.exe
kiwi, peach, banana
TJ (25), Jax (37), Alex (72)

In this C# version, we use the List<T> class’s Sort method, which accepts a Comparison<T> delegate. This allows us to provide custom sorting logic.

For sorting the Person objects, we use a lambda expression directly in the Sort method call. If the Person class is large, you might want to consider using a list of references (List<Person>) instead of values, which is already the case in C# (unlike structs in C#, classes are reference types by default).

Note that C# provides LINQ, which offers a more declarative way to sort collections. For example, you could use:

var sortedPeople = people.OrderBy(p => p.Age).ToList();

This approach can be more readable for simple sorting operations, but the Sort method with a custom comparer can be more efficient for complex or frequently used sorting logic.