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

C#:按可为空的DateTime属性对对象列表进行排序,c#,linq,C#,Linq,我有一个对象列表:List List=… 每个对象都有一个DateTime属性,我们称之为“Date” 我想按此日期属性降序排列此列表。然而,当我尝试 list.Sort(新比较((x,y)=>DateTime.Compare(x.Date,y.Date))) 它会抱怨,因为Date属性可以为空 如何对列表进行排序,将可为空的日期视为最大日期,使其显示在顶部?对我来说,快速简单的替代方法是不使日期字段为空,但让我们假设现在不允许这样做 简而言之:如果DateTime可以为空,如何按DateTim

我有一个对象列表:
List List=…

每个对象都有一个DateTime属性,我们称之为“Date”

我想按此日期属性降序排列此列表。然而,当我尝试

list.Sort(新比较((x,y)=>DateTime.Compare(x.Date,y.Date)))

它会抱怨,因为Date属性可以为空

如何对列表进行排序,将可为空的日期视为最大日期,使其显示在顶部?对我来说,快速简单的替代方法是不使日期字段为空,但让我们假设现在不允许这样做


简而言之:如果DateTime可以为空,如何按DateTime对对象列表排序?

一种可能的方法可能是:

list.Sort(new Comparison<FakeObject>((x, y) => 
    -DateTime.Compare(x.Date ?? DateTime.MaxValue,
        y.Date ?? DateTime.MaxValue)));
list.Sort(新比较((x,y)=>
-DateTime.Compare(x.Date×DateTime.MaxValue,
y、 日期??DateTime.MaxValue));
更新:修改为在OP编辑问题进行澄清后使用
MaxDate


请注意,您可以采用任何一种方式(
MinDate
MaxDate
)进行此操作。底线是这样的,如果它是空的,那么给它一些静态值来完成你想要的。

如果你想把所有空日期转换成最大日期值,那么就在你的函数中这样做。您可以使用null coalesce运算符来获得更简洁的语法:

list.Sort((x, y) => 
    DateTime.Compare(x.Date ?? DateTime.MaxValue, y.Date ?? DateTime.MaxValue))

在比较之前,将null date实例设置为MAX怎么样

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

…之后是对比较的调用。

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

list = list.OrderByDescending(x => x.Date ?? DateTime.MaxValue).ToList();

我会这样做

首先,给我们上这样的课

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

}

其中,
true
指定将空值整理得比任何其他值都高,
false
指定将空值整理得比任何值都低。

+1我的朋友,我很高兴我的答案模仿了你的答案,这让我感到谦卑!这会使列表中的值发生变化,这似乎是不可取的,他只是想在排序时将其用作有效值。啊。。是的,很公平!这也会按降序排列日期?@HenleyChiu,不,这不会排序
DESC
。要做到这一点,只需在末尾添加一个调用
Reverse
。将
排序
降序会更有效:要么交换
x
y
,要么在
日期时间前面放一个
-
(或者
-1*
,如果你觉得更清楚的话)。比较
。(同样,正如所写,它不编译。
Sort
返回
void
,而不是列表)@TimS.,现在这是一个有趣的方法。请验证我的编辑是否正确。我已经选择了一个答案。。。它只有一行,比你的简单多了。谢谢
widgetList.Sort( new WidgetComparer( true/false ) ) ;