НейроАгент

Как отсортировать List<T> по свойству в C#

Полное руководство по сортировке List<T> по свойству в C#. Узнайте о методах сортировки LINQ, синтаксисе запросов, пользовательских компараторах и сортировке по вложенным свойствам с практическими примерами.

Вопрос

Как отсортировать List по свойству в C#

У меня есть класс Order со свойствами, такими как OrderId, OrderDate, Quantity и Total. У меня есть список этого класса Order:

csharp
List<Order> objListOrder = new List<Order>();
GetOrderList(objListOrder); // заполнить список заказов

Я хочу отсортировать список на основе одного свойства объекта Order; например, по OrderDate или OrderID. Как можно отсортировать List по конкретному свойству в C#?

НейроАгент

Чтобы отсортировать List по определенному свойству в C#, можно использовать метод LINQ OrderBy() с лямбда-выражением, указывающим свойство, по которому нужно выполнить сортировку. Например, чтобы отсортировать ваш список заказов по OrderDate, используйте objListOrder.OrderBy(o => o.OrderDate).ToList(), а для сортировки в обратном порядке можно использовать objListOrder.OrderByDescending(o => o.OrderDate).ToList().

Содержание

Базовая сортировка с OrderBy

Наиболее распространенный подход для сортировки List по свойству - использование метода расширения LINQ OrderBy(). Этот метод принимает лямбда-выражение, указывающее, по какому свойству выполнять сортировку.

csharp
// Сортировка по OrderId (по возрастанию)
var sortedById = objListOrder.OrderBy(o => o.OrderId).ToList();

// Сортировка по OrderDate (по возрастанию) 
var sortedByDate = objListOrder.OrderBy(o => o.OrderDate).ToList();

// Сортировка по Quantity (по возрастанию)
var sortedByQuantity = objListOrder.OrderBy(o => o.Quantity).ToList();

// Сортировка по Total (по возрастанию)
var sortedByTotal = objListOrder.OrderBy(o => o.Total).ToList();

Метод OrderBy возвращает упорядоченную последовательность, которую можно преобразовать обратно в List с помощью .ToList().

Ключевые моменты:

  • OrderBy() выполняет сортировку по возрастанию по умолчанию
  • Лямбда-выражение o => o.PropertyName указывает свойство для сортировки
  • Результат представляет собой IOrderedEnumerable, который можно преобразовать в List

Сортировка в обратном порядке

Если вам нужна сортировка в обратном порядке, используйте метод OrderByDescending():

csharp
// Сортировка по OrderId (по убыванию)
var sortedByIdDesc = objListOrder.OrderByDescending(o => o.OrderId).ToList();

// Сортировка по OrderDate (по убыванию)
var sortedByDateDesc = objListOrder.OrderByDescending(o => o.OrderDate).ToList();

// Сортировка по Quantity (по убыванию)
var sortedByQuantityDesc = objListOrder.OrderByDescending(o => o.Quantity).ToList();

// Сортировка по Total (по убыванию)
var sortedByTotalDesc = objListOrder.OrderByDescending(o => o.Total).ToList();

Согласно документации Microsoft, OrderByDescending сортирует элементы в порядке убывания на основе указанного селектора ключа.


Множественные критерии сортировки с ThenBy

Когда требуется сортировка по нескольким свойствам, можно объединить OrderBy с ThenBy (или ThenByDescending для вторичных критериев):

csharp
// Сортировка по OrderId (основной), затем по OrderDate (вторичный)
var sortedMultiple = objListOrder
    .OrderBy(o => o.OrderId)
    .ThenBy(o => o.OrderDate)
    .ToList();

// Сортировка по OrderDate (основной), затем по Total (по убыванию)
var sortedDateThenTotal = objListOrder
    .OrderBy(o => o.OrderDate)
    .ThenByDescending(o => o.Total)
    .ToList();

// Сортировка по Quantity (по возрастанию), затем по OrderId (по убыванию)
var sortedQuantityThenId = objListOrder
    .OrderBy(o => o.Quantity)
    .ThenByDescending(o => o.OrderId)
    .ToList();

Метод ThenBy позволяет добавлять дополнительные критерии сортировки после основной операции OrderBy.

Использование синтаксиса запросов

Если вы предпочитаете синтаксис запросов вместо синтаксиса методов, можно использовать orderby:

csharp
// Синтаксис запросов - сортировка по OrderId
var sortedByIdQuery = from order in objListOrder
                     orderby order.OrderId
                     select order;

// Синтаксис запросов - сортировка по OrderDate по убыванию
var sortedByDateQuery = from order in objListOrder
                       orderby order.OrderDate descending
                       select order;

// Синтаксис запросов - множественные критерии сортировки
var sortedMultipleQuery = from order in objListOrder
                         orderby order.Quantity, order.Total descending
                         select order;

// Преобразование в List при необходимости
var sortedList = sortedByIdQuery.ToList();

Синтаксис запросов предоставляет альтернативный способ выражения операций сортировки, который некоторые разработчики считают более читаемым для сложных запросов, как упоминается в уроках по C#.


Сортировка по вложенным свойствам

Если ваш класс Order содержит вложенные объекты, можно сортировать по свойствам этих вложенных объектов:

csharp
// Предполагается, что у Order есть свойство Customer со свойством Name
var sortedByCustomerName = objListOrder
    .OrderBy(o => o.Customer.Name)
    .ToList();

// Сортировка с вложенными свойствами и несколькими уровнями
var sortedByNested = objListOrder
    .OrderBy(o => o.Customer.Name)
    .ThenBy(o => o.Store.Location.City)
    .ToList();

// Для коллекций внутри объектов используйте FirstOrDefault() или другие методы
var sortedByFirstAuthor = objListOrder
    .OrderBy(o => o.Authors.FirstOrDefault().Name)
    .ToList();

Microsoft Q&A предоставляет дополнительные примеры сортировки по вложенным свойствам.

Пользовательская сортировка с компараторами

Для более сложных сценариев сортировки можно создавать пользовательские компараторы:

csharp
// Пользовательский компаратор для OrderDate (игнорировать временную компоненту)
public class OrderDateComparer : IComparer<Order>
{
    public int Compare(Order x, Order y)
    {
        return x.OrderDate.Date.CompareTo(y.OrderDate.Date);
    }
}

// Использование пользовательского компаратора
var sortedByDateOnly = objListOrder
    .OrderBy(o => o.OrderDate, new OrderDateComparer())
    .ToList();

// Динамическая сортировка на основе выражений
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();
    }
}

// Использование
SortByProperty(objListOrder, o => o.OrderDate, true); // по возрастанию

Пользовательские компараторы дают полный контроль над логикой сортировки для сложных сценариев.


Полный пример с классом Order

Вот полный пример, показывающий, как реализовать и использовать сортировку с вашим классом Order:

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; }
    
    // Конструктор
    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()
    {
        // Создание и заполнение списка
        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("Исходный список:");
        PrintOrders(objListOrder);

        // Сортировка по OrderId (по возрастанию)
        var sortedById = objListOrder.OrderBy(o => o.OrderId).ToList();
        Console.WriteLine("\nОтсортировано по OrderId (по возрастанию):");
        PrintOrders(sortedById);

        // Сортировка по OrderDate (по убыванию)
        var sortedByDate = objListOrder.OrderByDescending(o => o.OrderDate).ToList();
        Console.WriteLine("\nОтсортировано по OrderDate (по убыванию):");
        PrintOrders(sortedByDate);

        // Сортировка по CustomerName, затем по Total (по убыванию)
        var sortedByCustomerThenTotal = objListOrder
            .OrderBy(o => o.CustomerName)
            .ThenByDescending(o => o.Total)
            .ToList();
        Console.WriteLine("\nОтсортировано по CustomerName, затем по Total (по убыванию):");
        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}");
        }
    }
}

Этот полный пример демонстрирует все обсужденные техники сортировки, предоставляя практическую ссылку для реализации сортировки в ваших собственных приложениях.

Заключение

  • Используйте OrderBy() для сортировки по возрастанию по любому свойству ваших объектов, например objListOrder.OrderBy(o => o.OrderDate).ToList()
  • Используйте OrderByDescending(), когда вам нужна сортировка по убыванию, например objListOrder.OrderByDescending(o => o.OrderId).ToList()
  • Объединяйте OrderBy с ThenBy для множественных критериев сортировки для создания сложной логики сортировки
  • Синтаксис запросов предлагает альтернативный читаемый подход с использованием orderby
  • Вложенные свойства можно сортировать, обращаясь к ним в лямбда-выражении
  • Пользовательские компараторы обеспечивают максимальную гибкость для сложных требований к сортировке

Методы сортировки LINQ эффективны, читаемы и предоставляют всю необходимую функциональность для сортировки коллекций по свойствам объектов в C#. Выберите подход, который лучше всего соответствует вашему стилю программирования и конкретным требованиям.

Источники

  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