c#如何实现自定义集合_c#自定义集合项目实例附完整源码
C#自定义集合开发指南:为何应优先继承Collection而非手动实现接口

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
在C#开发中,创建自定义集合类是一个常见需求。本文将深入探讨一个高效且安全的实现方案:优先继承Collection基类,而非手动实现IEnumerable或IList接口。这一选择能显著提升开发效率,确保数据绑定兼容性,并降低代码维护成本。
避免直接实现IEnumerable的三大理由
许多开发者初次尝试创建自定义集合时,会从实现IEnumerable接口开始。然而,这种方法存在几个根本性缺陷:
首先,IEnumerable仅定义了枚举遍历能力,不包含任何集合修改功能。这意味着您需要额外实现Add、Remove、Count等核心成员,工作量远超预期。
其次,LINQ扩展方法(如Where、Select)会返回新的IEnumerable实例,导致自定义集合的业务规则(如数据验证)在链式调用中丢失。
IEnumerable本质上是只读遍历协议,不提供集合修改能力- 手动实现完整
IList需要重写超过20个成员,极易遗漏关键方法 - WPF/WinForms数据绑定机制依赖
INotifyCollectionChanged接口,仅实现IEnumerable会导致UI无法自动更新
利用Collection基类快速构建业务集合
Collection是.NET框架专门为自定义集合开发设计的可扩展基类。其核心优势在于:
它将所有集合操作拆分为独立的可重写虚方法:InsertItem、RemoveItem、SetItem和ClearItems。开发者只需重写需要添加业务逻辑的方法,其余功能由基类自动处理。
以下示例展示如何创建“仅接受正整数”的自定义集合:
public class PositiveIntCollection : Collection{ protected override void InsertItem(int index, int item) { if (item <= 0) throw new ArgumentException("只允许添加正整数"); base.InsertItem(index, item); } protected override void SetItem(int index, int item) { if (item <= 0) throw new ArgumentException("只允许设置正整数"); base.SetItem(index, item); }}
- 自动获得完整的枚举器实现,支持foreach遍历和所有LINQ操作
- 所有修改入口(Add、Insert、索引器赋值)均被统一拦截,确保业务规则一致性
- 可轻松扩展集合变更通知机制,支持日志记录或UI自动刷新
手动实现
IList的适用场景与风险虽然继承基类是最佳实践,但在特定场景下仍需手动实现接口:
1. 性能关键型数据结构:如固定大小的环形缓冲区、内存池等需要极致性能的场景
2. 特殊内存布局需求:如将集合直接映射到非托管内存或特定数组结构
一个常见误区是试图通过
IList实现“智能过滤”集合。例如,创建自动跳过null元素的列表会遇到语义矛盾:Count属性应返回总长度还是非空元素数?索引器this[0]应返回第一个元素还是第一个非空元素?
IList契约要求Count属性必须为O(1)时间复杂度- 索引器必须直接访问物理位置元素,不能动态过滤后重新编排索引
- 过滤需求应使用LINQ的
Where方法,而非修改集合基础语义完整实战示例:带唯一性约束的排序集合
以下是一个可直接使用的C#自定义集合实现,兼具元素唯一性和自动排序功能:
public class SortedUniqueIntCollection : Collection{ private readonly SortedSet _inner = new(); public override int Count => _inner.Count; protected override void InsertItem(int index, int item) { if (_inner.Add(item)) base.InsertItem(index, item); else throw new InvalidOperationException($"重复值 {item} 不允许插入"); } protected override void RemoveItem(int index) { _inner.Remove(this[index]); base.RemoveItem(index); } protected override void ClearItems() { _inner.Clear(); base.ClearItems(); }}
重要说明:此实现使用
SortedSet辅助集合来维护唯一性和快速查找,但实际数据存储仍在基类的Items属性(List类型)中。因此,foreach遍历顺序为插入顺序,而非排序顺序。若需要严格按排序顺序遍历,建议封装
SortedSet并实现IEnumerable和IReadOnlyList接口。这一设计决策对集合行为有重要影响,应在项目初期明确需求。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
python什么时候用input_Python input 使用
Python 2与Python 3输入函数对比:核心差异与迁移指南 在Python语言的发展历程中,从Python 2升级到Python 3时,input函数的行为改变是一个必须掌握的关键语法变化。许多开发者在版本迁移过程中都曾在此处遇到问题。本文将深入解析Python 2和Python 3在输入处
python 查看python安装路径
Python开发者必备技能:快速定位Python安装路径的完整教程 Python中or运算符的赋值用法详解 Python编程在Excel自动化处理中的实际应用 编程乐趣探索:Python文件查看、输出与运行全攻略 Python安装路径在哪里?三种方法快速查找 1 整体流程概述 查找Python的安
PHP CGI、FastCGI、PHP-FPM、PHP-CGI 区别
PHP CGI、FastCGI、PHP-FPM、PHP-CGI:核心区别与性能深度解析 在搭建和优化PHP服务器环境时,PHP CGI、FastCGI、PHP-FPM与PHP-CGI这几个核心概念常常让开发者感到困惑。它们各自扮演着怎样的角色?对网站性能和服务器资源管理又有何不同影响?本文将为你彻底
php的特殊协议php://
php: 协议详解:PHP内置I O流的全面指南 在PHP开发中,除了常规的文件与网络操作,系统还内置了一套高效便捷的“特殊通道”——php: 协议族。这是一组功能强大的输入 输出(I O)流包装器,为开发者提供了直接访问PHP进程自身I O系统的途径。通过php: ,您可以轻松操作标准输入
c++如何解析MIME邮件格式中的Base64嵌入附件流【实战】
C++实战:高效解析MIME邮件中的Base64嵌入附件流 解码前关键步骤:剥离MIME头部与边界标记 许多开发者在处理MIME邮件附件时,常犯的第一个错误是直接对整个邮件正文调用 base64_decode 函数,这必然导致解码失败。原因在于,真实的Base64数据块被多层“包装”所包裹,包括 C
- 日榜
- 周榜
- 月榜
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
相关攻略
2015-03-10 11:25
2015-03-10 11:05
2021-08-04 13:30
2015-03-10 11:22
2015-03-10 12:39
2022-05-16 18:57
2025-05-23 13:43
2025-05-23 14:01
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程
热门话题

