Есть ли более краткий способ сортировки в C #? - PullRequest
2 голосов
/ 19 августа 2010

Допустим, у меня есть такая сущность, как:

public class Car
{
    public string Make { get; set; }
    public string Model { get; set; }
    public DateTime ReleaseDate { get; set; }
    public int NumCreated { get; set; }
}

Мы используем простую архитектуру MVP для нашего сайта с уровнем просмотра (сайт ASP.NET, уровень докладчика (библиотека классов C #), уровень логики(Библиотека классов C #), Уровень данных (Библиотека классов C #).

Допустим, у меня есть представление, отображающее список автомобилей с сортируемыми заголовками столбцов. В прошлом я делал все своисортировка в моем логическом слое, и представление, передающее перечисление для любого столбца, по которому должен быть отсортирован список сущностей.

Это боль, потому что мне нужно поддерживать перечисление для каждой сущности, которую я имею, изапись в этом перечислении для каждого свойства в сущности.

Так, например, мы будем делать что-то вроде:

CarLogic.cs

public IEnumerable<Car> GetCarsByYear(string year, SortColumn sortColumn, SortOrder sortOrder)
{
    List<Car> cars = _carRepository.GetCarsByYear(year);  

    switch (sortColumn)
    {
        case SortColumn.Make:
            cars.Sort((car1, car2) =>
                    sortOrder == SortOrder.Ascending
                    ? car1.Make.CompareTo(car2.Make) :
                      car2.Make.CompareTo(car1.Make);
            break;
       case SortColumn.Model:
            cars.Sort((car1, car2) =>
                    sortOrder == SortOrder.Ascending
                    ? car1.Model.CompareTo(car2.Model) :
                      car2.Model.CompareTo(car1.Model);
            break;
       case SortColumn.ReleaseDate:
            cars.Sort((car1, car2) =>
                    sortOrder == SortOrder.Ascending
                    ? car1.ReleaseDate.CompareTo(car2.ReleaseDate) :
                      car2.ReleaseDate.CompareTo(car1.ReleaseDate);
            break;
       case SortColumn.NumCreated:
            cars.Sort((car1, car2) =>
                    sortOrder == SortOrder.Ascending
                    ? car1.NumCreated.CompareTo(car2.NumCreated) :
                      car2.NumCreated.CompareTo(car1.NumCreated);
            break;
       // ...
    }

    return cars;
}

Вот какЯ делал это. Однако это очень ручной процесс, и если у объекта есть довольно много свойств, это может раздражать.

Что может быть лучше для этого? Можно ли разрешить моемуколлекция энтМожно ли сортировать свойства без необходимости делать все вручную для каждого свойства, как это?

Ответы [ 4 ]

12 голосов
/ 19 августа 2010

Лучший способ справиться с этим был бы следующим:

public IEnumerable<Car> GetCarsByYear<T>(string year, SortOrder sortOrder,
    Func<Car, T> fieldSelector) where T : IComparable<T>
{
    List<Car> cars = _carRepository.GetCarsByYear(year);  

    cars.Sort((car1, car2) =>
        sortOrder == sortOrder.Ascending
        ? fieldSelector(car1).CompareTo(fieldSelector(car2)) :
          fieldSelector(car2).CompareTo(fieldSelector(car1)));

    return cars;
}

GetCarsByYear(2010, SortOrder.Ascending,  c => c.Model);
GetCarsByYear(2008, SortOrder.Descending, c => c.Make);

Как уже упоминалось выше, было бы более естественным использовать OrderBy вместо сохранения его в списке.1005 *

0 голосов
/ 20 августа 2010

Лучший метод, который я могу придумать для этого, - это использовать метод

    static List<T> SortList<T>(List<T> list, string column)
    {
        foreach (PropertyInfo p in typeof(T).GetProperties())
        {
            if (p.Name == column)
            {
                return list.OrderBy(c => c.GetType().GetProperty(p.Name).GetValue(c, null)).ToList();
            }
        }
        return list;
    }

. Затем его можно вызвать с помощью

var sortedList = SortList<Car>(cars, "NumCreated");

. Поскольку он использует отражение, он будет работать длясписок любого объекта без необходимости изменения.

0 голосов
/ 19 августа 2010

Было бы проще отсортировать ваши коллекции, используя IComparer классы?

0 голосов
/ 19 августа 2010

Вы можете использовать LINQ to Objects для выполнения сортировки ваших сущностей

var sortedCars = cars.OrderBy(c => c.Model).ThenBy(c => c.Make);

Или же вы можете использовать OrderByDescending и ThenByDescending для сортировки по убыванию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...