【发布时间】:2011-02-07 08:30:53
【问题描述】:
在Stack<T> 上使用.ToList() 扩展方法时,结果是否与弹出每个元素并添加到新列表相同(与推送的内容相反)?
如果是这样,这是因为它确实在迭代每个元素,还是它在内部反向存储元素并将数组滑入新的List<T>?
【问题讨论】:
在Stack<T> 上使用.ToList() 扩展方法时,结果是否与弹出每个元素并添加到新列表相同(与推送的内容相反)?
如果是这样,这是因为它确实在迭代每个元素,还是它在内部反向存储元素并将数组滑入新的List<T>?
【问题讨论】:
Stack 本身没有ToList 方法,它是Enumerable 类的扩展方法。由于这些扩展方法只处理IEnumerable<T>,因此可以安全地假设ToList 迭代堆栈中的项目以创建新列表(或者至少就像它一样 - Enumerable 方法有时会测试参数的类型并使用优化的实现)。
有趣的是,文档似乎没有直接说明枚举堆栈的顺序,但示例代码确实显示了顺序,并且示例是文档的一部分。此外,在实践中,更改迭代顺序会破坏太多代码,以至于现在更改的风险太大。
我还检查了反射器; Stack<T> 将其项目存储在一个数组中,最底部的元素位于索引 0 处,但它的 Enumerator 以相反的顺序迭代数组。因此,从迭代器出来的第一个元素是栈顶。
【讨论】:
Stack<T> 的枚举器迭代顺序的任何内容,但也许我看起来不够好......
Stack.GetEnumerator 的示例显示了从后到前的顺序,并且示例中的堆栈反转操作不会如果不使用此排序,则无法工作(哎呀;正如 Jon Skeet 在他的回答中所说)。
ToList 将按照与您执行此操作相同的顺序进行迭代:
foreach (T item in stack)
据我所知,docs for GetEnumerator() 没有明确说明顺序,但该示例表明它会像弹出一样进行迭代。因此,如果您按下 1、2、3、4、5,那么 ToList 会给您 5、4、3、2、1。
【讨论】: