简体   繁体   English

C#:按可以为空的DateTime属性排序对象列表

[英]C#: sort list of objects by DateTime property that is nullable

I have a List of objects: List<FakeObject> list = ... 我有一个对象List<FakeObject> list = ...List<FakeObject> list = ...

Each object has a DateTime property, let's call it "Date" 每个对象都有一个DateTime属性,我们称之为“Date”

I want to sort this list by this date property in descending order. 我想按此日期属性按降序排序此列表。 However, when I try 但是,当我尝试

list.Sort(new Comparison<FakeObject>((x, y) => DateTime.Compare(x.Date, y.Date)))

it complains because the Date property can be nullable. 它抱怨,因为Date属性可以为空。

How do I sort this list, where it treats nullable dates as MAX DATE, so it appears in the top? 如何对此列表进行排序,将可空日期视为MAX DATE,将其显示在顶部? The quick easy alternative for me is to NOT make the Date field nullable, but let's suppose that's not an option right now. 对我来说,快速简单的替代方法是不要使Date字段可以为空,但让我们假设现在不是一个选项。

In short: How do I sort a list of objects by DateTime, if the DateTime can be null? 简而言之:如果DateTime可以为null,我如何按DateTime对对象列表进行排序?

One possible approach might be: 一种可能的方法可能是:

list.Sort(new Comparison<FakeObject>((x, y) => 
    -DateTime.Compare(x.Date ?? DateTime.MaxValue,
        y.Date ?? DateTime.MaxValue)));

UPDATE: modified to use MaxDate after the OP edited the question for clarification. 更新:修改为在OP编辑问题后使用MaxDate进行说明。

Note that you could do this either way ( MinDate or MaxDate ). 请注意,您可以采用这种方式( MinDateMaxDate )。 The bottom line is this, if it's null then give it some static value that accomplishes what you want. 底线是这个,如果它是null那么给它一些静态值来完成你想要的。

If you want to convert all null dates to the max date value then just do that in your function. 如果要将所有空日期转换为最大日期值,请在函数中执行此操作。 You can use the null coalesce operator for a more succinct syntax for this: 您可以使用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();

How about just setting the null date instances to MAX before the comparision? 如何在比较之前将空日期实例设置为MAX?

list.ForEach(x => x.Date = x.Date ?? null : DateTime.Max : x.Date);

...followed by the call to your compare.. ......然后是你的比较号召......

I'd do something like this. 我会做这样的事情。

First, given a class like this 首先,给出这样的课程

class Widget
{
    public DateTime? DateCreated { get ; set ; }
}

I'd write a custom comparer, something like this: 我会写一个自定义比较器,如下所示:

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

}

Then it's a simple matter of 那么这很简单

widgetList.Sort( new WidgetComparer( true/false ) ) ;

where true specifies to collate nulls higher than anything else and false to collate them lower than anything else. 其中true指定整理高于其他任何值的空值而false指定整理它们低于其他任何值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM