У меня есть класс с именем , Order
который имеет свойства , такие как OrderId
, OrderDate
, Quantity
, и Total
. У меня есть список этого Order
класса:
List<Order> objListOrder = new List<Order>();
GetOrderList(objListOrder); // fill list of orders
Теперь я хочу отсортировать список по одному свойству Order
объекта, например, мне нужно отсортировать его по дате заказа или идентификатору заказа.
Как я могу сделать это в C #?
Ответы:
Самый простой способ, который я могу придумать, это использовать Linq:
источник
listWithObjects = listWithObjects.OrderByDescending(o => o.Status).ToList();
достаточно для такого усилия?Если вам нужно отсортировать список на месте, вы можете использовать
Sort
метод, передаваяComparison<T>
делегат:Если вы предпочитаете создавать новую, отсортированную последовательность, а не сортировать на месте, вы можете использовать
OrderBy
метод LINQ , как упоминалось в других ответах.источник
x
иy
на правой стороне стрелки=>
.Nullable<>
(возьмемDateTime?
в качестве примера) вы можете использовать,.Sort((x, y) => Nullable.Compare(x.OrderDate, y.OrderDate))
который будет обрабатывать нуль как предшествующий всем ненулевым значениям. Это точно так же, как.Sort((x, y) => Comparer<DateTime?>.Default.Compare(x.OrderDate, y.OrderDate)
.Чтобы сделать это без LINQ на .Net2.0:
Если вы используете .Net3.0, то ответ LukeH - то, что вам нужно.
Чтобы сортировать по нескольким свойствам, вы все равно можете сделать это внутри делегата. Например:
Это даст вам восходящие даты с нисходящим порядковым номером.
Тем не менее, я бы не рекомендовал придерживаться делегатов, так как это будет означать много мест без повторного использования кода. Вы должны реализовать
IComparer
и просто передать это своемуSort
методу. Смотрите здесь .А затем, чтобы использовать этот класс IComparer, просто создайте его экземпляр и передайте его в свой метод Sort:
источник
IComparer
реализации, дающие нам полиморфное поведение.Самый простой способ заказать список состоит в использовании
OrderBy
Если вы хотите упорядочить по нескольким столбцам, например, следуя SQL-запросу.
Для достижения этой цели вы можете использовать
ThenBy
как следующие.источник
Делать это без Линка, как вы сказали:
Затем просто вызовите .sort () в вашем списке заказов
источник
null
наas
актерский состав. В этом вся суть тогоas
, как (ха, ха)(Order)obj
выдает исключение, когда оно терпит неудачу.if(orderToCompare == null) return 1;
,as
вернется,null
если произойдет сбой. Но по крайней мере нулевой тест верен.List<Order>
так что тип должен гарантированно совпадать сas
тем, что в 2014 году вы, вероятно, не написали ошибку, а избежали ненужного защитного оператора :)List<Order>
; но вы и я встретили самозакрывающегося программиста, который не высказал предположение, что «я пишу этот код, чтобы он не использовался неправильно»Классическое объектно-ориентированное решение
Во-первых, я должен преувеличить удивительность LINQ .... Теперь, когда мы получили это с дороги
Вариация на ответ Джимми Хоффа. При использовании дженериков
CompareTo
параметр становится безопасным для типов.Сортируемость по умолчанию, конечно, можно использовать повторно. То есть каждому клиенту не нужно избыточно переписывать логику сортировки. Обмен «1» и «-1» (или логические операторы по вашему выбору) меняет порядок сортировки.
источник
this
объект больше нуля. В целях сортировки нулевая ссылка на объект "меньше чем"this
объект. Именно так я решил определить, как будут сортироваться нули.// Полностью универсальная сортировка для использования с gridview
источник
data.OrderBy()
. Немного проще, чем изобретать велосипед.Вот общий метод расширения LINQ, который не создает дополнительную копию списка:
Чтобы использовать это:
Недавно я построил этот дополнительный, который принимает
ICompare<U>
, так что вы можете настроить сравнение. Это пригодилось, когда мне нужно было выполнить сортировку строк Natural:источник
OrderBy
делает все это внутренне.void
метод расширения в этом духе:static class Extensions { public static void SortBy<TSource, TKey>(this List<TSource> self, Func<TSource, TKey> keySelector) { self.SortBy(keySelector, Comparer<TKey>.Default); } public static void SortBy<TSource, TKey>(this List<TSource> self, Func<TSource, TKey> keySelector, IComparer<TKey> comparer) { self.Sort((x, y) => comparer.Compare(keySelector(x), keySelector(y))); } }
может быть дополненSortByDescending
методом. Комментарии @ Servy также применимы и к моему коду!Использование LINQ
источник
источник
Улучшенная версия Роджера.
Проблема с GetDynamicSortProperty заключается в том, что получают только имена свойств, но что произойдет, если в GridView мы используем NavigationProperties? он отправит исключение, так как находит ноль.
Пример:
"Employee.Company.Name;" завершится сбоем ..., так как позволяет только "Name" в качестве параметра получить его значение.
Вот улучшенная версия, которая позволяет нам сортировать по свойствам навигации.
источник
Вы можете сделать что-то более общее с выбором свойств, но быть конкретным с типом, из которого вы выбираете, в вашем случае 'Order':
напишите свою функцию как общую:
и затем используйте это так:
Вы можете быть еще более универсальными и определить открытый тип для того, что вы хотите заказать:
и использовать его так же:
Это глупый ненужный сложный способ выполнения стиля OrderQy в LINQ, но он может дать вам представление о том, как его можно реализовать в общем виде.
источник
Пожалуйста, позвольте мне дополнить ответ @LukeH некоторым примером кода, так как я проверял его, я думаю, что он может быть полезен для некоторых:
источник
источник
Используйте LiNQ
OrderBy
источник
На основе Comparer GenericTypeTea :
мы можем добиться большей гибкости, добавив флаги сортировки:
В этом сценарии необходимо явно создать его как MyOrderingClass (а не IComparer )
, чтобы установить его свойства сортировки:
источник
Ни один из приведенных выше ответов не был достаточно общим для меня, поэтому я сделал этот:
Осторожнее с массивными данными, хотя. Это простой код, но он может доставить вам неприятности, если коллекция огромна, а тип объекта коллекции имеет большое количество полей. Время выполнения NxM, где:
N = количество элементов в коллекции
M = количество свойств внутри объекта
источник
Любой, работающий с обнуляемыми типами,
Value
обязан использоватьCompareTo
.objListOrder.Sort((x, y) => x.YourNullableType.Value.CompareTo(y.YourNullableType.Value));
источник
С точки зрения производительности лучше всего использовать отсортированный список, чтобы данные сортировались по мере их добавления в результат. Другие подходы требуют, по крайней мере, одну дополнительную итерацию для данных, и большинство создает копию данных, так что это влияет не только на производительность, но и на использование памяти. Может не быть проблем с парой сотен элементов, но будет с тысячами, особенно в сервисах, где многие одновременные запросы могут выполнять сортировку одновременно. Взгляните на пространство имен System.Collections.Generic и выберите класс с сортировкой вместо List.
И избегайте универсальных реализаций, использующих отражение, когда это возможно, это может также вызвать проблемы с производительностью.
источник
Предположим, у вас есть следующий код, в этом коде у нас есть класс Passenger с парой свойств, которые мы хотим отсортировать на основе.
Таким образом, вы можете реализовать свою структуру сортировки с помощью делегата Composition.
источник