stack 必须用泛型 new stack() 创建,支持 push/pop/peek 操作,空栈调用后两者抛 invalidoperationexception;遍历用 foreach(顶到底),初始化数组会逆序入栈;注意无索引器、非线程安全、clear 不安全。

Stack 初始化和基本操作
直接用 new Stack<t>()</t> 创建实例,泛型参数必须明确指定。别用非泛型 Stack(已过时),它装 object、要装箱拆箱、没类型安全。
常用操作就是 Push() 入栈、Pop() 出栈顶、Peek() 看栈顶但不移除。注意 Pop() 和 Peek() 在空栈上调用会抛 InvalidOperationException。
var stack = new Stack<string>();
stack.Push("first");
stack.Push("second");
Console.WriteLine(stack.Peek()); // 输出 "second"
Console.WriteLine(stack.Pop()); // 输出 "second",栈变只剩 "first"
判断是否为空和遍历栈
Count 属性返回当前元素个数,Count == 0 或直接用 Any()(需 using System.Linq)判断是否为空。不要用 Count > 0 做循环条件来反复 Pop()——这会破坏原始数据。
如果只是想“看一遍”内容且不改变栈,用 foreach 遍历是安全的,它按从顶到底顺序访问(即最后 Push 的最先被枚举):
var stack = new Stack<int> { 1, 2, 3 };
foreach (var item in stack) {
Console.Write(item + " "); // 输出:3 2 1
}
从数组或集合初始化 Stack
构造函数支持 IEnumerable<t></t>,传入数组、列表甚至另一个 Stack<t></t> 都可以。但要注意:传入的集合会被**逆序**压入新栈——因为栈是后进先出,要保持原序列“最先出现的元素在栈底”,就得反着压。
- 数组
new[] { 1, 2, 3 }初始化Stack<int></int>→ 栈内从顶到底是3, 2, 1 - 若想保持顺序(即 1 在顶),得先
Reverse()再传入:new Stack<int>(arr.Reverse())</int>
常见误用和性能注意点
Stack<t></t> 底层是动态数组,Push() 和 Pop() 平均时间复杂度 O(1),但频繁扩容可能触发内存拷贝。如果预估容量较大,建议用带容量的构造函数:new Stack<int>(1024)</int>。
容易踩的坑:
- 把
Stack<t></t>当作“可随机访问容器”——它没有索引器,不能写stack[0] - 误以为
Clear()是线程安全的——它不是,多线程读写必须加锁或改用ConcurrentStack<t></t> - 在
foreach中调用Pop()——会抛InvalidOperationException(集合被修改)
真正需要后进先出语义时再用 Stack<t></t>;如果只是临时存几项又反复查,List<t></t> 加 Insert(0, x) 和 RemoveAt(0) 反而更慢且易错。









