问题 .NET中的stack.ToList() - 元素的顺序?


使用时 .ToList() 一个扩展方法 Stack<T>,结果与弹出每个元素并添加到新列表相反(推送的内容相反)?

如果是这样,这是因为它实际上是迭代每个元素,或者它是否在内部反向存储元素并将数组滑入一个新元素 List<T>


8219
2018-04-13 08:30


起源



答案:


Stack 本身没有 ToList 方法,它是来自的扩展方法 Enumerable 类。由于这些扩展方法只处理 IEnumerable,可以安全地假设 ToList 迭代堆栈的项目以创建新列表。

更新:我用Reflector检查过; Stack<T> 将其项目存储在一个数组中,其中最下面的元素位于索引0处,但是它 Enumerator 迭代数组 以相反的顺序。因此,从迭代器出来的第一个元素是堆栈的顶部。


11
2018-04-13 08:32



假设为什么安全?我无法在文档中找到任何说明枚举器的顺序的内容 Stack<T> 迭代,但也许我看起来不够好...... - Mark Seemann
它并没有直截了当地说(至少现在不是这样),而是一个例子 的文件 Stack.GetEnumerator 显示最后到第一个顺序,如果没有使用这个排序,示例中的堆栈反转操作将不起作用(oops;正如Jon Skeet在他的回答中所说)。 - dlf


答案:


Stack 本身没有 ToList 方法,它是来自的扩展方法 Enumerable 类。由于这些扩展方法只处理 IEnumerable,可以安全地假设 ToList 迭代堆栈的项目以创建新列表。

更新:我用Reflector检查过; Stack<T> 将其项目存储在一个数组中,其中最下面的元素位于索引0处,但是它 Enumerator 迭代数组 以相反的顺序。因此,从迭代器出来的第一个元素是堆栈的顶部。


11
2018-04-13 08:32



假设为什么安全?我无法在文档中找到任何说明枚举器的顺序的内容 Stack<T> 迭代,但也许我看起来不够好...... - Mark Seemann
它并没有直截了当地说(至少现在不是这样),而是一个例子 的文件 Stack.GetEnumerator 显示最后到第一个顺序,如果没有使用这个排序,示例中的堆栈反转操作将不起作用(oops;正如Jon Skeet在他的回答中所说)。 - dlf


ToList 将按照与执行此操作相同的顺序迭代:

foreach (T item in stack)

docs for docs GetEnumerator() 我没有明确说明顺序,但是示例显示它会像弹出一样迭代。所以,如果你再推1,2,3,4,5 ToList 会给你5,4,3,2,1。


5
2018-04-13 08:35