C# LINQ Ordering Operators

As was shown in the LINQ introduction, both query and method syntax provide a means of ordering data using the 'orderby' operator. Both types of syntax provide a number of other options to help with ordering data. The table below shows the methods available in method syntax. Query syntax has an equivalent for all of these, except 'Reverse'.

Method Description
OrderBy Returns the elements sorted in ascending order.
ThenBy Returns the elements sorted in ascending order.
OrderByDescending Returns the elements sorted in descending order.
ThenByDescending Returns the elements sorted in descending order.
Reverse Returns the elements in reverse order.

Below are some examples of each of these methods that can be used for ordering data.

class Program
{

    static void Main(string[] args)
    {

        // List containing person objects.
        List<Person> people = new List<Person>()
        {
            { new Person(1, "Bob", "Smith", "Mr", new DateTime(1980, 01, 20)) },
            { new Person(3, "Fred", "Bloggs", "Mr", new DateTime(1975, 05, 07)) },
            { new Person(4, "Alan", "White", "Mr", new DateTime(1989, 03, 20)) },
            { new Person(5, "Fiona", "Bloggs", "Mrs", new DateTime(1985, 05, 19)) },
            { new Person(6, "Zoe", "Davis", "Miss", new DateTime(1979, 07, 11)) },
            { new Person(7, "Tom", "Ingram", "Mr", new DateTime(1971, 10, 04)) },
            { new Person(8, "Karen", "Thomas", "Mrs", new DateTime(1969, 03, 08)) },
            { new Person(9, "Samantha", "Yates", "Miss", new DateTime(1995, 08, 27)) }
        };

        Console.WriteLine("Query syntax, OrderBy and ThenBy:");
        Console.WriteLine();

        // LINQ query syntax.
        var listOrderQS = (from person in people
                           orderby person.lastName,
                                   person.firstName
                           select person).ToList();

        // Display information relating to people that match the criteria.
        DisplayPeople(listOrderQS);

        Console.WriteLine();
        Console.WriteLine("Method syntax, OrderBy and ThenBy methods:");
        Console.WriteLine();

        // LINQ method syntax.
        var listOrderMS = people.OrderBy(p => p.lastName)
                                .ThenBy(p => p.firstName).ToList();

        // Display information relating to people that match the criteria.
        DisplayPeople(listOrderMS);

        Console.WriteLine();
        Console.WriteLine("Query syntax, OrderByDescending/ThenByDescending:");
        Console.WriteLine();

        // LINQ query syntax.
        var listOrderDescQS = (from person in people
                               orderby person.lastName descending,
                                       person.firstName descending
                               select person).ToList();

        // Display information relating to people that match the criteria.
        DisplayPeople(listOrderDescQS);

        Console.WriteLine();
        Console.WriteLine("Method syntax, OrderByDescending/ThenByDescending methods:");
        Console.WriteLine();

        // LINQ method syntax.
        var listOrderDescMS = people.OrderByDescending(p => p.lastName)
                                    .ThenByDescending(p => p.firstName).ToList();

        // Display information relating to people that match the criteria.
        DisplayPeople(listOrderDescMS);

        Console.WriteLine();
        Console.WriteLine("Method syntax, Reverse method:");
        Console.WriteLine();

        // LINQ method syntax.
        var listReverseMS = people.OrderBy(p => p.lastName)
                                  .ThenBy(p => p.firstName)
                                  .Reverse().ToList();

        // Display information relating to people that match the criteria.
        DisplayPeople(listReverseMS);

    }

    // Method to display a list of 'Person' objects.
    private static void DisplayPeople(List<Person> people)
    {

        foreach (Person person in people)
        {

            // Variable to construct person details to display.
            string personDetails = "";

            // Construct the person information for display.
            personDetails += person.id + ") ";
            personDetails += person.firstName + " " + person.lastName;
            personDetails += " - Age: " + person.CalculateAge();
            personDetails += " (" + person.dob.Day.ToString().PadLeft(2, '0') + "/";
            personDetails += person.dob.Month.ToString().PadLeft(2, '0') + "/";
            personDetails += person.dob.Year + ")";

            // Display the constructed person information.
            Console.WriteLine(personDetails);

        }

    }

}

class Person
{

    public int id;
    public string firstName;
    public string lastName;
    public string title;
    public DateTime dob;

    // Constructor.
    public Person(int pId, string pFirsName, string pLastName, string pTitle, DateTime pDob)
    {

        id = pId;
        firstName = pFirsName;
        lastName = pLastName;
        title = pTitle;
        dob = pDob;

    }

    // Method to calculate a person's age.
    public int CalculateAge()
    {

        // Get the current date.
        DateTime dateToday = DateTime.Today;

        // Calculate the age.
        int currentAge = dateToday.Year - dob.Year;

        if (dob.Month > dateToday.Month ||
            (dob.Month == dateToday.Month && dob.Day > dateToday.Day))
        {
            currentAge -= 1;
        }

        return currentAge;

    }

}

There are a few things to note here. Query syntax implicitly implements the 'ThenBy' functionality as a comma separated list of items within 'orderby'. Both 'OrderByDescending' and 'ThenByDescending' are implemented in query syntax by including the word 'descending' after the item being ordered by, within 'orderby'.

Here is the output in the console from these examples.

Query syntax, OrderBy and ThenBy:

5) Fiona Bloggs - Age: 36 (19/05/1985)
3) Fred Bloggs - Age: 46 (07/05/1975)
6) Zoe Davis - Age: 41 (11/07/1979)
7) Tom Ingram - Age: 49 (04/10/1971)
1) Bob Smith - Age: 41 (20/01/1980)
8) Karen Thomas - Age: 52 (08/03/1969)
4) Alan White - Age: 32 (20/03/1989)
9) Samantha Yates - Age: 25 (27/08/1995)

Method syntax, OrderBy and ThenBy methods:

5) Fiona Bloggs - Age: 36 (19/05/1985)
3) Fred Bloggs - Age: 46 (07/05/1975)
6) Zoe Davis - Age: 41 (11/07/1979)
7) Tom Ingram - Age: 49 (04/10/1971)
1) Bob Smith - Age: 41 (20/01/1980)
8) Karen Thomas - Age: 52 (08/03/1969)
4) Alan White - Age: 32 (20/03/1989)
9) Samantha Yates - Age: 25 (27/08/1995)

Query syntax, OrderByDescending/ThenByDescending:

9) Samantha Yates - Age: 25 (27/08/1995)
4) Alan White - Age: 32 (20/03/1989)
8) Karen Thomas - Age: 52 (08/03/1969)
1) Bob Smith - Age: 41 (20/01/1980)
7) Tom Ingram - Age: 49 (04/10/1971)
6) Zoe Davis - Age: 41 (11/07/1979)
3) Fred Bloggs - Age: 46 (07/05/1975)
5) Fiona Bloggs - Age: 36 (19/05/1985)

Method syntax, OrderByDescending/ThenByDescending methods:

9) Samantha Yates - Age: 25 (27/08/1995)
4) Alan White - Age: 32 (20/03/1989)
8) Karen Thomas - Age: 52 (08/03/1969)
1) Bob Smith - Age: 41 (20/01/1980)
7) Tom Ingram - Age: 49 (04/10/1971)
6) Zoe Davis - Age: 41 (11/07/1979)
3) Fred Bloggs - Age: 46 (07/05/1975)
5) Fiona Bloggs - Age: 36 (19/05/1985)

Method syntax, Reverse method:

9) Samantha Yates - Age: 25 (27/08/1995)
4) Alan White - Age: 32 (20/03/1989)
8) Karen Thomas - Age: 52 (08/03/1969)
1) Bob Smith - Age: 41 (20/01/1980)
7) Tom Ingram - Age: 49 (04/10/1971)
6) Zoe Davis - Age: 41 (11/07/1979)
3) Fred Bloggs - Age: 46 (07/05/1975)
5) Fiona Bloggs - Age: 36 (19/05/1985)