C#容器源码分析 --- Stack<T>

在 C# 中,Stack<T> 是一个泛型集合类,它位于 System.Collections.Generic 命名空间下,实现了后进先出(LIFO,Last-In-First-Out)的数据结构, 其核心实现基于动态数组。

.Net4.8 Stack<T>源码地址:
stack.cs (microsoft.com)https://referencesource.microsoft.com/#System/compmod/system/collections/generic/stack.cs,c5371bef044c6ab6

内部结构:

1.主要字段属性:

类似于List<T>中的内部数据结构:
_array :这是一个泛型数组,用于实际存储 Stack<T> 中的元素。Stack 里的元素都存放在这个数组中。
_size :表示当前 Stack<T> 中实际存储的元素数量,反映了栈中有效元素的个数。
_version :用于记录 Stack<T> 的版本号。每当对栈进行添加、删除等修改操作时,这个版本号会增加。它主要用于在迭代栈时检测栈是否被修改,如果被修改则会抛出异常,以保证迭代的安全性。
_defaultCapacity :这是一个常量,代表 Stack<T> 的默认初始容量,值为 4。当创建一个 Stack<T> 对象且未指定初始容量时,会使用这个默认值。
_emptyArray :这是一个静态只读的空数组,用于在某些情况下表示空栈。
Count:返回_size,当前存储的元素数量。

2.构造方法:

类似于List<T>的构造函数:

1.无参构造函数

2.指定初始容量的构造函数

3.从现有集合初始化的构造函数

动态扩容机制:

类似于List的动态扩容机制,默认在达到数组最大长度时,将数组长度扩大两倍。

主要方法:

1.Peek:

2.Pop:

3.Push:

4.TrimExcess:

5.Contains:

解释:使用EqualityComparer<T>.Default判断是否于目标是否一致
EqualityComparer<T>.Default 是一个静态属性,用于获取类型 T 的默认相等比较器。它会根据类型 T 是否实现 IEquatable<T> 接口,自动选择最合适的比较逻辑。
规则

1.若 T 实现了 IEquatable<T>,则使用其 Equals 方法。

2.若 T 未实现 IEquatable<T>,则回退到 object.Equals(值类型按值比较,引用类型按引用比较)。

3.自动处理 T 为可空类型(如 int?)的情况。

EqualityComparer<T>中的CreateComparer方法源码看出,在执行此方法时会按照T的类型返回一个比较器赋值给EqualityComparer<T>.Default,比较器内部都实现了Equals方法,若T内部实现了Equals方法就使用T内部的。

注:

typeof(IEquatable<T>)​​:获取 IEquatable<T> 接口的 Type 对象。

​​.IsAssignableFrom(t)​​:判断类型 t 的实例是否可以赋值给 IEquatable<T> 类型的变量,即 t 是否实现了该接口。

相关推荐
极小狐4 小时前
极狐GitLab 命名空间的类型有哪些?
运维·git·c#·ssh·gitlab
夏子曦6 小时前
C#——NET Core 中实现汉字转拼音
开发语言·c#
zxy284722530110 小时前
C#上传文件到腾讯云的COS
c#·腾讯云·cos·oss·存储桶
冰茶_10 小时前
WPF之高级绑定技术
microsoft·微软·c#·wpf·mvvm·数据绑定
冰茶_11 小时前
WPF之尺寸属性层次
microsoft·微软·c#·wpf·布局系统
钢铁男儿13 小时前
深入解析C#参数传递:值参数 vs 引用参数
java·开发语言·c#
lrf201914 小时前
C#管道通讯及传输信息丢失的原因
c#·管道通讯
babytiger18 小时前
如何用命令行判断一个exe是不是c#wpf开发的
开发语言·c#·wpf
scimence20 小时前
DeepSeek API接口调用示例(开发语言C#,替换其中key值为自己的key值即可)
开发语言·人工智能·c#·api接口·deepseek
一个会的不多的人1 天前
C# NX二次开发:投影曲线和偏置曲线UFUN函数详解
java·开发语言·前端·c#