我有这个代码,它只是根据每个整数中的数字编号对整数的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是否再次排序? (它已经排序了吗?)
答案 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));