在我的代码中,我很少有堆栈用来跟踪我的逻辑位置。在某些时候,我需要复制堆栈,但我似乎不能以这样的方式复制它们,它保持了顺序。我只需要浅复制(引用,而不是对象)。
正确的方法是什么?或者我应该使用其他类型的堆栈?
我看到这篇文章Stack Clone Problem: .NET Bug or Expected Behaviour?,但不知道如何设置Stack<T>
类的克隆方法。
我使用System.Collection.Generic.Stack<T>
。
在我的代码中,我很少有堆栈用来跟踪我的逻辑位置。在某些时候,我需要复制堆栈,但我似乎不能以这样的方式复制它们,它保持了顺序。我只需要浅复制(引用,而不是对象)。
正确的方法是什么?或者我应该使用其他类型的堆栈?
我看到这篇文章Stack Clone Problem: .NET Bug or Expected Behaviour?,但不知道如何设置Stack<T>
类的克隆方法。
我使用System.Collection.Generic.Stack<T>
。
4条答案
按热度按时间7gs2gvoe1#
您可以将其编写为扩展方法
这是必要的,因为我们这里使用的
Stack<T>
构造函数是Stack<T>(IEnumerable<T> source)
,当然,当你迭代Stack<T>
的IEnumerable<T>
实现时,它会重复地从堆栈中弹出项,从而以与你希望它们进入新堆栈的顺序相反的顺序将它们提供给你。两次执行该过程将导致堆栈处于正确的顺序。或者:
同样,我们必须按照与迭代堆栈的输出相反的顺序遍历堆栈。
我怀疑这两种方法之间是否存在性能差异。
lf3rwulv2#
对于那些关心性能的人来说..还有一些其他的方法来迭代原始的堆栈成员而不会对性能造成大的损失:
我编写了一个粗略的程序(链接将在文章末尾提供)来测量性能,并为已经建议的实现添加了两个测试(参见 * Clone1 * 和 * Clone2 *),以及为ToArray和CopyTo方法添加了两个测试(参见 * Clone3 * 和 * Clone4 *,它们都使用了更高效的 * Array. Reverse * 方法)。
结果如下:
正如我们所看到的,使用 * CopyTo * 方法的方法要快8倍,同时实现也非常简单和直接。此外,我还快速研究了堆栈大小的最大值:* Clone3 * 和 * Clone4 * 测试在 * OutOfMemoryException * 发生之前适用于更大的堆栈大小:
由于显式/隐式定义了额外的集合,因此影响了内存消耗,因此 * Clone1 * 和 * Clone2 * 的上述结果较小。因此,* Clone3 * 和 * Clone4 * 方法允许更快地克隆堆栈示例,并使用更少的内存分配。使用反射可以获得更好的结果,但情况不同:)
完整的程序列表可在here中找到。
4si2a6ki3#
这里有一个简单的方法,使用LINQ:
您可以创建一个扩展方法来简化此操作:
用法:
s5a0g9ez4#
如果你不需要一个实际的
Stack
1,而只是想要一个现有
Stack1
的快速拷贝,你可以按照Pop
返回的顺序遍历它,另一个选择是将Stack
1复制到
Queue1
中,然后元素将按照从原始Stack
1到
Pop的相同顺序进行
Dequeue`。输出: