IEnumerable <t>上的延迟OrderBy

时间:2015-12-22 00:55:37

标签: c# linq ienumerable

我有这个代码,它只是根据每个整数中的数字编号对整数的IEnumerable进行排序。

var ints = new List<int>() { 66, 7, 9, -5, -22, 67, 122, -333, 555, -2 };
var ordered = ints.OrderBy(x =>
{
   x = Math.Abs(x);

   Console.WriteLine($"Getting length of {x}");

   int len = 0;
   while (x >= 1)
   {
      len++;
      x /= 10;
   }
   return len;
});

   Console.WriteLine("After OrderBy");
   Console.WriteLine("Fetching first item in ordered sequence");
   Console.WriteLine($"First item is {ordered.First()}");

   Console.WriteLine(string.Join(" ", ordered));

所以,当程序在那一刻点击ordered序列中的第一个项目时,IEnumerable正在排序(我正在接收输出行Getting lenght of XXX),因为OrderBy被推迟了很清楚。

但是为什么当程序命中Console.WriteLine(string.Join(" ", ordered));时我又会得到这个输出? IEnumerable是否再次排序? (它已经排序了吗?)

2 个答案:

答案 0 :(得分:3)

将值分配给ordered时,实际上并未对它们进行排序。它基本上是订购列表的指令。 IOrderedEnumerable<int>。因此,每次您尝试访问第一个项目或任何其他项目时,它都会将其转换为有序列表,以便为您提供该项目。第一次运行.First()时,第二次运行string.Join 在这两种情况下,程序将创建2个不同的有序列表实例,使用它,然后通过丢失引用来处置它(因为你没有保存它)。

答案 1 :(得分:0)

如果您需要仅对Ordered进行一次排序,则需要在其上调用ToList(),在这种情况下,您将只看到一次列表结果。自订购以来。

var ints = new List<int>() { 66, 7, 9, -5, -22, 67, 122, -333, 555, -2 };
var ordered = ints.OrderBy(x =>
{
    x = Math.Abs(x);

    Console.WriteLine($"Getting length of {x}");

    int len = 0;
    while (x >= 1)
    {
        len++;
        x /= 10;
    }
    return len;
}).ToList();

Console.WriteLine("After OrderBy");
Console.WriteLine("Fetching first item in ordered sequence");
Console.WriteLine($"First item is {ordered.First()}");
Console.WriteLine(string.Join(" ", ordered));