Question

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

csharpgenericslistsorting

Question

I have a class named Order with properties such as OrderId, OrderDate, Quantity, and Total. I also have a list of Order objects:

List<Order> objListOrder = new List<Order>();
GetOrderList(objListOrder); // Fill the list of orders

I want to sort this list based on one property of the Order object, such as OrderDate or OrderId.

How can I sort a List<Order> by a property in C#?

Short Answer

By the end of this page, you will understand how to sort a List<T> by one of an object's properties in C#. You will learn the difference between List.Sort() and LINQ methods like OrderBy() and OrderByDescending(), when to use each one, and how to sort by multiple properties safely and clearly.

Concept

Sorting a list of objects means arranging the items in a specific order based on one or more values inside each object.

In this case, each item in the list is an Order object. Since Order has properties like OrderId and OrderDate, you can sort the list using one of those properties as the sorting key.

In C#, there are two very common ways to do this:

  • List<T>.Sort(...) — sorts the existing list in place
  • LINQ OrderBy(...) / OrderByDescending(...) — returns a new sorted sequence

This matters in real programming because object collections are everywhere:

  • showing records in a UI
  • sorting API results
  • ordering reports by date
  • processing highest or lowest values first
  • grouping and displaying business data in a meaningful way

The key idea is simple: you tell C# which property to compare, and C# uses that property to arrange the objects.

For example:

  • sort by OrderId for numeric order
  • sort by OrderDate for chronological order
  • sort by Total to see cheapest or most expensive orders first

If you need only a quick one-time sorted result, LINQ is usually very readable. If you want to permanently reorder the existing List<Order>, Sort() is often the better fit.

Mental Model

Think of a list of Order objects like a stack of paper order forms.

Each form has multiple fields:

  • Order ID
  • Date
  • Quantity
  • Total

Sorting means choosing one field to look at and arranging all forms by that field.

  • If you sort by OrderDate, you line them up from oldest to newest.
  • If you sort by OrderId, you line them up by ID number.
  • If you sort by Total, you line them up by price.

So the object is the full form, and the property is the specific column you use to organize it.

Take Quiz

Syntax and Examples

Using List<T>.Sort()

Use Sort() when you want to reorder the original list.

objListOrder.Sort((x, y) => x.OrderId.CompareTo(y.OrderId));

This compares the OrderId of two Order objects and sorts them in ascending order.

Sort by date

objListOrder.Sort((x, y) => x.OrderDate.CompareTo(y.OrderDate));

This sorts the list from earliest date to latest date.

Using LINQ OrderBy()

Use OrderBy() when you want a sorted result without modifying the original list.

var sortedById = objListOrder.OrderBy(o => o.OrderId).ToList();

Sort by date

var sortedByDate = objListOrder.OrderBy(o => o.OrderDate).ToList();

Descending order

var latestFirst = objListOrder.OrderByDescending(o => o.OrderDate).ToList();

Sorting by multiple properties

If two orders have the same date, you can break ties with another property.

var sortedOrders = objListOrder
    .OrderBy(o => o.OrderDate)
    .ThenBy(o => o.OrderId)
    .ToList();

This sorts by OrderDate first, then by OrderId when dates are equal.

Example class and data

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; }
}

var orders = new List<Order>
{
    new Order { OrderId = 3, OrderDate = new DateTime(2024, 2, 10), Quantity = 2, Total = 50.00m },
    new Order { OrderId = 1, OrderDate = new DateTime(2024, 1, 15), Quantity = 5, Total = 120.00m },
    new Order { OrderId = 2, OrderDate = new DateTime(2024, 1, 15), Quantity = 1, Total = 20.00m }
};

var sorted = orders
    .OrderBy(o => o.OrderDate)
    .ThenBy(o => o.OrderId)
    .ToList();

After sorting, the order of OrderId values will be:

  • 1
  • 2
  • 3

because orders 1 and 2 share the same date, and ThenBy() sorts them by ID.

Step by Step Execution

Consider this code:

var sorted = objListOrder.OrderBy(o => o.OrderDate).ToList();

Here is what happens step by step:

  1. objListOrder is the original list of Order objects.
  2. OrderBy(o => o.OrderDate) tells C# to use each order's OrderDate as the sorting key.
  3. LINQ examines each item and reads its OrderDate.
  4. It arranges the items from smallest to largest date.
    • earlier dates come first
    • later dates come after
  5. ToList() creates a new List<Order> containing the sorted items.
  6. The original objListOrder is unchanged unless you assign the result back.

Example:

var orders = new List<Order>
{
    new Order { OrderId = 10, OrderDate = new DateTime(2024, 5, 1) },
    new Order { OrderId = 11, OrderDate = new DateTime(2024, 1, 1) },
    new Order { OrderId = 12, OrderDate = new DateTime(2024, 3, 1) }
};

var sorted = orders.OrderBy(o => o.OrderDate).ToList();

Trace

Original order:

  • 10 → 2024-05-01
  • 11 → 2024-01-01
  • 12 → 2024-03-01

Sorted by OrderDate:

  • 11 → 2024-01-01
  • 12 → 2024-03-01
  • 10 → 2024-05-01

If you instead do this:

objListOrder.Sort((x, y) => x.OrderDate.CompareTo(y.OrderDate));

then the same list object is rearranged directly. No new list is created.

Real World Use Cases

Sorting object lists by properties is very common in real applications.

Common scenarios

  • E-commerce systems: sort orders by date, total amount, or status
  • Admin dashboards: show newest records first
  • Reports: sort invoices by customer, month, or amount
  • APIs: prepare data in a predictable order before returning it
  • Desktop apps: display rows in sorted grids or tables
  • Data processing scripts: process oldest or highest-priority items first

Examples

Show newest orders first

var recentOrders = orders
    .OrderByDescending(o => o.OrderDate)
    .ToList();

Show highest-value orders first

var topOrders = orders
    .OrderByDescending(o => o.Total)
    .ToList();

Sort for cleaner reporting

var reportOrders = orders
    .OrderBy(o => o.OrderDate)
    .ThenBy(o => o.OrderId)
    .ToList();
Take Quiz

Real Codebase Usage

In real codebases, sorting is often combined with filtering, validation, and display logic.

Common patterns

1. Sort after filtering

var openOrders = orders
    .Where(o => o.Total > 0)
    .OrderBy(o => o.OrderDate)
    .ToList();

Developers often filter first, then sort the remaining data.

2. Use early checks before sorting

if (orders == null || orders.Count == 0)
{
    return new List<Order>();
}

var sortedOrders = orders.OrderBy(o => o.OrderId).ToList();

This prevents errors and makes the code safer.

3. Sort by user-selected columns

string sortBy = "OrderDate";

var sorted = sortBy switch
{
    "OrderId" => orders.OrderBy(o => o.OrderId).ToList(),
    "Total" => orders.OrderBy(o => o.Total).ToList(),
    _ => orders.OrderBy(o => o.OrderDate).ToList()
};

This pattern appears in APIs, grid views, and search pages.

4. Stable multi-column sorting for UI tables

var sorted = orders
    .OrderBy(o => o.OrderDate)
    .ThenBy(o => o.OrderId)
    .ToList();

This makes sorting more predictable when multiple rows share the same first value.

5. In-place sorting for performance-sensitive code

orders.Sort((a, b) => a.Total.CompareTo(b.Total));

When developers already have a List<T> and want to reuse it, this is often simpler and avoids creating another list.

Common Mistakes

1. Forgetting that OrderBy() does not change the original list

Broken assumption:

objListOrder.OrderBy(o => o.OrderId);

This does not sort objListOrder in place.

Correct:

objListOrder = objListOrder.OrderBy(o => o.OrderId).ToList();

Or use Sort():

objListOrder.Sort((x, y) => x.OrderId.CompareTo(y.OrderId));

2. Using Sort() on something that is not a List<T>

Sort() is a method on List<T>, not on every collection type.

If you have an IEnumerable<Order>, use LINQ:

var sorted = orders.OrderBy(o => o.OrderDate).ToList();

3. Comparing the wrong types manually

Broken code:

objListOrder.Sort((x, y) => x.OrderDate > y.OrderDate ? 1 : -1);

This can fail to handle equality clearly.

Better:

objListOrder.Sort((x, y) => x.OrderDate.CompareTo(y.OrderDate));

CompareTo() correctly handles less than, equal to, and greater than.

4. Forgetting descending order methods

Broken idea: sorting ascending and expecting largest values first.

Correct:

var sorted = objListOrder.OrderByDescending(o => o.Total).ToList();

5. Ignoring null values in sortable properties

If a property can be null, sorting may need extra care.

Example with nullable date:

var sorted = orders
    .OrderBy(o => o.OrderDate ?? DateTime.MaxValue)
    .ToList();

This puts missing dates at the end.

6. Sorting strings when you actually want numbers

If OrderId were stored as a string, sorting could be unexpected:

// "1", "10", "2"
var sorted = orders.OrderBy(o => o.OrderId).ToList();

That would sort alphabetically, not numerically. Use numeric types for numeric values whenever possible.

Comparisons

ApproachModifies original list?Returns new sequence?Best for
List<T>.Sort()YesNoReordering an existing List<T>
OrderBy()NoYesReadable query-style sorting
OrderByDescending()NoYesReverse ordering
ThenBy()NoYesSecondary sorting

Sort() vs OrderBy()

FeatureSort()OrderBy()
Works directly on List<T>YesYes
Changes original listYesNo
Returns a new list automaticallyNoNo, but can with ToList()
Good for chaining with Where()Less convenientVery convenient
Easy for multiple sort levelsPossible, but less readableVery readable with ThenBy()

When to choose each

  • Use Sort() when:

    • you already have a List<T>
    • you want to update that same list
    • you want an in-place sort
  • Use OrderBy() when:

    • you want cleaner query-style code
    • you are already using LINQ
    • you want to keep the original list unchanged
    • you need ThenBy() for multi-level sorting
Take Quiz

Cheat Sheet

Quick syntax

Sort existing list in place

objListOrder.Sort((x, y) => x.OrderId.CompareTo(y.OrderId));

Sort by date in place

objListOrder.Sort((x, y) => x.OrderDate.CompareTo(y.OrderDate));

Create a new sorted list

var sorted = objListOrder.OrderBy(o => o.OrderId).ToList();

Descending order

var sorted = objListOrder.OrderByDescending(o => o.OrderDate).ToList();

Sort by multiple properties

var sorted = objListOrder
    .OrderBy(o => o.OrderDate)
    .ThenBy(o => o.OrderId)
    .ToList();

Rules to remember

  • Sort() changes the original List<T>.
  • OrderBy() returns a sorted sequence and does not change the original list.
  • Use ToList() if you want a new List<T> from OrderBy().
  • Use CompareTo() inside Sort() comparisons.
  • Use ThenBy() or ThenByDescending() for tie-breakers.

Common property types that sort well

  • int
  • decimal
  • DateTime
  • string

Edge case

If a sortable property can be null, handle it explicitly:

var sorted = orders.OrderBy(o => o.OrderDate ?? DateTime.MaxValue).ToList();

FAQ

How do I sort a List<Order> by a property in C#?

Use either:

objListOrder.Sort((x, y) => x.OrderId.CompareTo(y.OrderId));

or:

var sorted = objListOrder.OrderBy(o => o.OrderId).ToList();

What is the difference between Sort() and OrderBy() in C#?

Sort() changes the original List<T>. OrderBy() returns a new sorted sequence and leaves the original collection unchanged unless you assign the result.

How do I sort a list of objects by date in C#?

var sorted = objListOrder.OrderBy(o => o.OrderDate).ToList();

For descending order:

var sorted = objListOrder.OrderByDescending(o => o.OrderDate).ToList();

How do I sort by more than one property?

Use ThenBy() or ThenByDescending():

var sorted = objListOrder
    .OrderBy(o => o.OrderDate)
    .ThenBy(o => o.OrderId)
    .ToList();

Does OrderBy() sort the original list?

No. It returns a sorted result. Use ToList() and assign it if you want a new list variable.

Can I sort descending with Sort()?

Yes:

objListOrder.Sort((x, y) => y.OrderId.CompareTo(x.OrderId));

Which approach is better for beginners?

OrderBy() is often easier to read. Sort() is useful when you specifically want to modify the existing list.

Take Quiz

Mini Project

Description

Build a small order-reporting tool that sorts customer orders in different ways. This project demonstrates how object-property sorting is used in real programs, such as admin dashboards and report generation.

Goal

Create a C# program that stores a list of orders and displays them sorted by ID, date, and total.

Requirements

  1. Create an Order class with OrderId, OrderDate, Quantity, and Total properties.
  2. Add at least five sample Order objects to a list.
  3. Display the orders sorted by OrderId in ascending order.
  4. Display the orders sorted by OrderDate in descending order.
  5. Display the orders sorted by Total, and use OrderId as a tie-breaker.
  6. Print the sorted results to the console clearly.
Take Quiz

Keep learning

Related questions

View more