且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

清单< T>和IEnumerable差异

更新时间:2022-06-25 20:35:57

您的功能是正确的 - 如果你检查的结果合并,你会看到结果的排序(例如)。结果
以便哪来的什么问题?正如你怀疑,你正在测试它错了 - 当你调用排序你原来名单上的更改,从它派生的所有集合! >结果
以下是一个演示你做了什么一个片段:

Your function is correct - if you inspect the result of Merge, you'll see the result is sorted (example).
So where's the problem? Just as you've suspected, you're testing it wrong - when you call Sort on your original list you change all collections that derive from it!
Here's a snippet that demonstrates what you did:

List<int> numbers = new List<int> {5, 4};
IEnumerable<int> first = numbers.Take(1);
Console.WriteLine(first.Single()); //prints 5
numbers.Sort();
Console.WriteLine(first.Single()); //prints 4!



所有的藏品都基本相同第一 - 在某种程度上,他们是懒惰的指针位置在整数。很显然,当你调用了ToList ,问题就消除了。

All collections you create are basically the same as first - in a way, they are lazy pointers to positions in ints. Obviously, when you call ToList, the problem is eliminated.

您的情况是比这更复杂。你的排序是部分懒惰,完全按照自己的建议:首先你创建一个列表( arrSorted ),并添加整数它。这部分不懒了,你看到排序的前几个元素的原因。接下来,添加剩余的元素 - 但是的毗连是懒惰。现在,递归进入乱这甚至更多:在大多数情况下,你的的IEnumerable 大部分元素都渴望 - 你创建列表出来的左,右,这也由大多渴望慵懒+尾。你结束了一个排序的列表&LT; INT&GT; ,懒洋洋地concated一个懒惰的指针,它应该是的刚刚过去的元素的(其他元素合并。前)结果
这里是你的函数调用图 - 红色表示一个懒惰的收集,黑实数:

Your case is more complex than that. Your Sort is part lazy, exactly as you suggest: First you create a list (arrSorted) and add integers to it. That part isn't lazy, and is the reason you see the first few elements sorted. Next, you add the remaining elements - but Concat is lazy. Now, recursion enters to mess this even more: In most cases, most elements on your IEnumerable are eager - you create lists out of left and right, which are also made of mostly eager + lazy tail. You end up with a sorted List<int>, lazily concated to a lazy pointer, which should be just the last element (other elements were merged before).
Here's a call graph of your functions - red indicated a lazy collection, black a real number:

清单&LT; T&GT;和IEnumerable差异

当您更改列表中的新名单大多是完好的,但最后一个元素很懒,并指向最大的元素在原列表中的位置。

When you change the list the new list is mostly intact, but the last element is lazy, and point to the position of the largest element in the original list.

其结果大多是不错的,但它的最后一个元素仍然指向原来的列表:

The result is mostly good, but its last element still points to the original list:

清单&LT; T&GT;和IEnumerable差异

最后一个例子:考虑你改变原来的列表中的所有元素。正如你所看到的,有序集合中的大多数元素保持不变,但最后是懒惰,指向新值:

One last example: consider you're changing all elements in the original list. As you can see, most elements in the sorted collection remain the same, but the last is lazy and points to the new value:

var ints = new List<int> { 3,2,1 };
var mergeSortInt = new MergeSort<int>();
var sortedInts = mergeSortInt.Sort(ints);
// sortedInts is { 1, 2, 3 }
for(int i=0;i<ints.Count;i++) ints[i] = -i * 10;
// sortedInts is { 1, 2, 0 }

下面是关于Ideone相同的例子: http://ideone.com/FQVR7

Here's the same example on Ideone: http://ideone.com/FQVR7