OrderBy [Descending]()和SkipWhile()的意外行为

Mik*_*iar 1 c# linq

我看到一些我很难理解的行为.给定一个DateTimes 列表,我只想按降序选择过去一年中发生的日期.但是使用OrderBy(),OrderByDescending()并且SkipWhile()正在表演.....奇怪.给出从今天开始的列表,包括过去100个月这样的列表:

List<DateTime> ldt = new List<DateTime>();
for (int i = 0; i < 100; i++)
{
    ldt.Add(DateTime.Now.AddMonths(-i));
}
Run Code Online (Sandbox Code Playgroud)

我从以下代码开始:

ldt = ldt.OrderByDescending(date => date).
          SkipWhile(date => date <= DateTime.Now.AddYears(-1)).ToList();
Run Code Online (Sandbox Code Playgroud)

这会正确地对列表进行排序,但不会跳过任何记录.所以为了好玩,我尝试了这个(跳过比今天早的一切,即一切):

 ldt = ldt.OrderByDescending(date => date).
            SkipWhile(date => date <= DateTime.Now).ToList();
Run Code Online (Sandbox Code Playgroud)

哪个有效.该列表为空.然后我尝试了以下(OrderBy而不是OrderByDescending):

ldt = ldt.OrderBy(date => date).
          SkipWhile(date => date <= DateTime.Now.AddYears(-1)).ToList(); 
Run Code Online (Sandbox Code Playgroud)

其工作完全符合预期 - 列表已订购,日期已正确过滤.所以最终的结果是:

ldt = ldt.OrderBy(date => date).
          SkipWhile(date => date <= DateTime.Now.AddYears(-1)).ToList();
ldt = ldt.OrderByDescending(date => date).ToList();
Run Code Online (Sandbox Code Playgroud)

跳过,然后重新订购.那我错过了什么?为什么其中一些工作,有些突破不可预测的方式?对于我正在尝试做的事情,正确的一行命令是什么?

Jon*_*eet 5

基本上,你想要TakeWhile而不是SkipWhile:

ldt = ldt.OrderByDescending(date => date)
         .TakeWhile(date => date > DateTime.Now)
         .ToList();
Run Code Online (Sandbox Code Playgroud)

使用OrderByDescending完之后,您要保留的条目是一个......而SkipWhile假设您要丢弃一些条目,然后保留其余条目.

(或者你可以过滤使用Where然后排序,正如里德建议的那样.两者都可以工作里德可能更有效率.使用你觉得更容易理解的.)

当你对这样的事情感到困惑时,有时候值得在一张纸上写出数据的例子.计算出每个步骤后序列的样子,然后确定下一步的作用.