C#: сортировка списка объектов по свойству DateTime, которое является nullable
у меня есть список объектов: List<FakeObject> list = ...
каждый объект имеет свойство DateTime, назовем его "Date"
Я хочу отсортировать этот список по этому свойству даты в порядке убывания. Однако, когда я пытаюсь
list.Sort(new Comparison<FakeObject>((x, y) => DateTime.Compare(x.Date, y.Date)))
Он жалуется, потому что свойство Date может быть nullable.
как отсортировать этот список, где он обрабатывает нулевые даты как максимальную дату, поэтому он появляется в верхней части? Быстрая легкая альтернатива для меня-не назначать дату поле nullable, но предположим, что это не вариант прямо сейчас.
короче говоря: как отсортировать список объектов по DateTime, если DateTime может быть null?
5 ответов
одним из возможных подходов может быть:
list.Sort(new Comparison<FakeObject>((x, y) =>
-DateTime.Compare(x.Date ?? DateTime.MaxValue,
y.Date ?? DateTime.MaxValue)));
обновление: изменен, чтобы использовать MaxDate
после того, как OP отредактировал вопрос для уточнения.
обратите внимание, что вы можете сделать это в любом случае (MinDate
или MaxDate
). Суть в следующем, если это null
затем дайте ему некоторое статическое значение, которое выполняет то, что вы хотите.
Если вы хотите преобразовать все нулевые даты в максимальное значение даты, просто сделайте это в своей функции. Для более краткого синтаксиса можно использовать оператор null coalesce:
list.Sort((x, y) =>
DateTime.Compare(x.Date ?? DateTime.MaxValue, y.Date ?? DateTime.MaxValue))
Если вы можете заменить список, вместо того, чтобы изменять его на месте, вы можете использовать LINQ.
list = list.OrderByDescending(x => x.Date ?? DateTime.MaxValue).ToList();
Как насчет того, чтобы просто установить нулевые экземпляры даты в MAX перед сравнением?
list.ForEach(x => x.Date = x.Date ?? null : DateTime.Max : x.Date);
...затем следует призыв к вашему сравнению..
Я бы сделал что-то вроде этого.
во-первых, учитывая класс такой
class Widget
{
public DateTime? DateCreated { get ; set ; }
}
Я бы написал пользовательский компаратор, что-то вроде этого:
class Widget
{
public DateTime? DateCreated { get ; set ; }
}
class WidgetComparer : IComparer<Widget> , IComparer<DateTime?>
{
public bool NullCollatesHigh { get ; private set ; }
private WidgetComparer( bool nullCollatesHigh )
{
this.NullCollatesHigh = nullCollatesHigh ;
return ;
}
public int Compare( Widget x , Widget y )
{
int cc ;
if ( x == null && y == null ) cc = 0 ;
else if ( x != null && y != null ) cc = Compare( x.DateCreated , y.DateCreated ) ;
else if ( NullCollatesHigh ) cc = x == null ? +1 : -1 ;
else cc = x == null ? -1 : +1 ;
return cc ;
}
public int Compare(DateTime? x, DateTime? y)
{
int cc ;
if ( x == null && y == null ) cc = 0 ;
else if ( x != null && y != null ) cc = DateTime.Compare( x.Value , y.Value ) ;
else if ( NullCollatesHigh ) cc = x == null ? +1 : -1 ;
else cc = x == null ? -1 : +1 ;
return cc ;
}
}
тогда это простой вопрос
widgetList.Sort( new WidgetComparer( true/false ) ) ;
здесь true
указывает для сортировки нулей выше, чем что-либо еще и false
чтобы сопоставить их ниже, чем что-либо еще.