7

I have a List of objects: List<FakeObject> list = ...

Each object has a DateTime property, let's call it "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.

How do I sort this list, where it treats nullable dates as MAX DATE, so it appears in the top? 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.

In short: How do I sort a list of objects by DateTime, if the DateTime can be null?

4

5 回答 5

16

一种可能的方法可能是:

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

更新:修改为MaxDate在 OP 编辑​​问题后使用以进行澄清。

请注意,您可以通过任何方式(MinDateMaxDate)执行此操作。最重要的是,如果是这样,null那么给它一些静态值来完成你想要的。

于 2013-11-01T18:42:17.400 回答
6

如果您想将所有空日期转换为最大日期值,那么只需在您的函数中执行此操作。您可以使用 null coalesce 运算符来获得更简洁的语法:

list.Sort((x, y) => 
    DateTime.Compare(x.Date ?? DateTime.MaxValue, y.Date ?? DateTime.MaxValue))
于 2013-11-01T18:42:48.523 回答
5

如果您可以替换列表,而不是就地修改它,则可以使用 LINQ。

list = list.OrderByDescending(x => x.Date ?? DateTime.MaxValue).ToList();
于 2013-11-01T18:45:10.773 回答
0

我会做这样的事情。

首先,给定一个像这样的类

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

wheretrue指定将空值整理得比其他任何东西都高,并将false它们整理得比其他任何东西都低。

于 2013-11-01T19:33:26.057 回答
0

在比较之前将空日期实例设置为 MAX 怎么样?

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

...然后调用您的比较..

于 2013-11-01T18:42:48.743 回答