NeuroAgent

How to Sort List<T> by Property in C#

Complete guide to sorting List<T> by property in C#. Learn LINQ sorting methods, query syntax, custom comparers, and nested property sorting with practical examples.

Question

How to Sort a List by a Property in C#

I have a class called Order with properties such as OrderId, OrderDate, Quantity, and Total. I have a list of this Order class:

csharp
List<Order> objListOrder = new List<Order>();
GetOrderList(objListOrder); // fill list of orders

I want to sort the list based on one property of the Order object; for example, either by OrderDate or OrderID.

How can I sort a List by a specific property in C#?

NeuroAgent

To sort a List by a specific property in C#, you can use LINQ’s OrderBy() method with a lambda expression that specifies the property you want to sort by. For example, to sort your Order list by OrderDate, you would use objListOrder.OrderBy(o => o.OrderDate).ToList() or for descending order, you can use objListOrder.OrderByDescending(o => o.OrderDate).ToList().

Contents

Basic Sorting with OrderBy

The most common approach to sort a List by a property is to use LINQ’s OrderBy() extension method. This method takes a lambda expression that specifies which property to sort by.

csharp
// Sort by OrderId (ascending)
var sortedById = objListOrder.OrderBy(o => o.OrderId).ToList();

// Sort by OrderDate (ascending) 
var sortedByDate = objListOrder.OrderBy(o => o.OrderDate).ToList();

// Sort by Quantity (ascending)
var sortedByQuantity = objListOrder.OrderBy(o => o.Quantity).ToList();

// Sort by Total (ascending)
var sortedByTotal = objListOrder.OrderBy(o => o.Total).ToList();

The OrderBy method returns an ordered sequence that can be converted back to a List using .ToList().

Key Points:

  • OrderBy() performs an ascending sort by default
  • The lambda expression o => o.PropertyName specifies the property to sort by
  • The result is an IOrderedEnumerable that you can convert to a List

Sorting in Descending Order

If you need to sort in descending order, use the OrderByDescending() method instead:

csharp
// Sort by OrderId (descending)
var sortedByIdDesc = objListOrder.OrderByDescending(o => o.OrderId).ToList();

// Sort by OrderDate (descending)
var sortedByDateDesc = objListOrder.OrderByDescending(o => o.OrderDate).ToList();

// Sort by Quantity (descending)
var sortedByQuantityDesc = objListOrder.OrderByDescending(o => o.Quantity).ToList();

// Sort by Total (descending)
var sortedByTotalDesc = objListOrder.OrderByDescending(o => o.Total).ToList();

According to the Microsoft documentation, OrderByDescending sorts elements in descending order based on the specified key selector.


Multiple Sorting Criteria with ThenBy

When you need to sort by multiple properties, you can combine OrderBy with ThenBy (or ThenByDescending for secondary criteria):

csharp
// Sort by OrderId (primary), then by OrderDate (secondary)
var sortedMultiple = objListOrder
    .OrderBy(o => o.OrderId)
    .ThenBy(o => o.OrderDate)
    .ToList();

// Sort by OrderDate (primary), then by Total (descending)
var sortedDateThenTotal = objListOrder
    .OrderBy(o => o.OrderDate)
    .ThenByDescending(o => o.Total)
    .ToList();

// Sort by Quantity (ascending), then by OrderId (descending)
var sortedQuantityThenId = objListOrder
    .OrderBy(o => o.Quantity)
    .ThenByDescending(o => o.OrderId)
    .ToList();

The ThenBy method allows you to add additional sorting criteria after the primary OrderBy operation.

Using Query Syntax

If you prefer query syntax over method syntax, you can use the orderby clause:

csharp
// Query syntax - sort by OrderId
var sortedByIdQuery = from order in objListOrder
                     orderby order.OrderId
                     select order;

// Query syntax - sort by OrderDate descending
var sortedByDateQuery = from order in objListOrder
                       orderby order.OrderDate descending
                       select order;

// Query syntax - multiple sorting criteria
var sortedMultipleQuery = from order in objListOrder
                         orderby order.Quantity, order.Total descending
                         select order;

// Convert to List if needed
var sortedList = sortedByIdQuery.ToList();

Query syntax provides an alternative way to express sorting operations that some developers find more readable for complex queries, as mentioned in the C# tutorials.


Sorting by Nested Properties

If your Order class contains nested objects, you can sort by properties of those nested objects:

csharp
// Assuming Order has a Customer property with Name property
var sortedByCustomerName = objListOrder
    .OrderBy(o => o.Customer.Name)
    .ToList();

// Nested sorting with multiple levels
var sortedByNested = objListOrder
    .OrderBy(o => o.Customer.Name)
    .ThenBy(o => o.Store.Location.City)
    .ToList();

// For collections within objects, use FirstOrDefault() or other methods
var sortedByFirstAuthor = objListOrder
    .OrderBy(o => o.Authors.FirstOrDefault().Name)
    .ToList();

The Microsoft Q&A provides additional examples of sorting by nested properties.

Custom Sorting with Comparers

For more complex sorting scenarios, you can create custom comparers:

csharp
// Custom comparer for OrderDate (ignore time component)
public class OrderDateComparer : IComparer<Order>
{
    public int Compare(Order x, Order y)
    {
        return x.OrderDate.Date.CompareTo(y.OrderDate.Date);
    }
}

// Use the custom comparer
var sortedByDateOnly = objListOrder
    .OrderBy(o => o.OrderDate, new OrderDateComparer())
    .ToList();

// Expression-based dynamic sorting
public void SortByProperty<T>(List<T> list, Expression<Func<T, object>> orderByExpression, bool ascending)
{
    if (ascending)
    {
        list = list.AsQueryable().OrderBy(orderByExpression).ToList();
    }
    else
    {
        list = list.AsQueryable().OrderByDescending(orderByExpression).ToList();
    }
}

// Usage
SortByProperty(objListOrder, o => o.OrderDate, true); // ascending

Custom comparers give you full control over the sorting logic for complex scenarios.


Complete Example with Order Class

Here’s a complete example showing how to implement and use sorting with your Order class:

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

public class Order
{
    public int OrderId { get; set; }
    public DateTime OrderDate { get; set; }
    public int Quantity { get; set; }
    public decimal Total { get; set; }
    public string CustomerName { get; set; }
    
    // Constructor
    public Order(int orderId, DateTime orderDate, int quantity, decimal total, string customerName)
    {
        OrderId = orderId;
        OrderDate = orderDate;
        Quantity = quantity;
        Total = total;
        CustomerName = customerName;
    }
}

public class Program
{
    public static void Main()
    {
        // Create and populate the list
        List<Order> objListOrder = new List<Order>
        {
            new Order(3, new DateTime(2023, 12, 15), 5, 150.00m, "Alice"),
            new Order(1, new DateTime(2023, 12, 10), 3, 90.00m, "Bob"),
            new Order(2, new DateTime(2023, 12, 20), 8, 240.00m, "Alice"),
        };

        Console.WriteLine("Original list:");
        PrintOrders(objListOrder);

        // Sort by OrderId (ascending)
        var sortedById = objListOrder.OrderBy(o => o.OrderId).ToList();
        Console.WriteLine("\nSorted by OrderId (ascending):");
        PrintOrders(sortedById);

        // Sort by OrderDate (descending)
        var sortedByDate = objListOrder.OrderByDescending(o => o.OrderDate).ToList();
        Console.WriteLine("\nSorted by OrderDate (descending):");
        PrintOrders(sortedByDate);

        // Sort by CustomerName, then by Total (descending)
        var sortedByCustomerThenTotal = objListOrder
            .OrderBy(o => o.CustomerName)
            .ThenByDescending(o => o.Total)
            .ToList();
        Console.WriteLine("\nSorted by CustomerName, then by Total (descending):");
        PrintOrders(sortedByCustomerThenTotal);
    }

    private static void PrintOrders(List<Order> orders)
    {
        foreach (var order in orders)
        {
            Console.WriteLine($"OrderID: {order.OrderId}, Date: {order.OrderDate:yyyy-MM-dd}, " +
                            $"Qty: {order.Quantity}, Total: {order.Total:C}, Customer: {order.CustomerName}");
        }
    }
}

This complete example demonstrates all the sorting techniques discussed, providing a practical reference for implementing sorting in your own applications.

Conclusion

  • Use OrderBy() for ascending sorting by any property of your objects, such as objListOrder.OrderBy(o => o.OrderDate).ToList()
  • Use OrderByDescending() when you need descending order, like objListOrder.OrderByDescending(o => o.OrderId).ToList()
  • Combine OrderBy with ThenBy for multiple sorting criteria to create complex sorting logic
  • Query syntax offers an alternative readable approach using orderby clauses
  • Nested properties can be sorted by accessing them in the lambda expression
  • Custom comparers provide maximum flexibility for complex sorting requirements

The LINQ sorting methods are efficient, readable, and provide all the functionality you need to sort collections by object properties in C#. Choose the approach that best fits your coding style and specific requirements.

Sources

  1. How to sort a C# List by a property in the object - Dofactory
  2. How to Sort a List by a property in the object - Stack Overflow
  3. Sorting Data - C# | Microsoft Learn
  4. Sorting data: the OrderBy() & ThenBy() methods - C# Tutorial
  5. LINQ Syntax: Sort C# List - C# Tutorials Blog
  6. Sort List by Property in the Object in .NET - Code Maze
  7. How to sort List with LINQ using Nested Property - Microsoft Q&A
  8. C# sort List - sorting list elements in C# language - ZetCode
  9. Enumerable.OrderBy Method - Microsoft Learn
  10. C# How to sort a list of objects by any property - Stack Overflow