首页 游戏 软件 资讯 排行榜 专题
首页
编程语言
c#如何实现自定义集合_c#自定义集合项目实例附完整源码

c#如何实现自定义集合_c#自定义集合项目实例附完整源码

热心网友
28
转载
2026-04-15

C#自定义集合开发指南:为何应优先继承Collection而非手动实现接口

c#如何实现自定义集合_c#自定义集合项目实例附完整源码

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

在C#开发中,创建自定义集合类是一个常见需求。本文将深入探讨一个高效且安全的实现方案:优先继承Collection基类,而非手动实现IEnumerableIList接口。这一选择能显著提升开发效率,确保数据绑定兼容性,并降低代码维护成本。

避免直接实现IEnumerable的三大理由

许多开发者初次尝试创建自定义集合时,会从实现IEnumerable接口开始。然而,这种方法存在几个根本性缺陷:

首先,IEnumerable仅定义了枚举遍历能力,不包含任何集合修改功能。这意味着您需要额外实现AddRemoveCount等核心成员,工作量远超预期。

其次,LINQ扩展方法(如WhereSelect)会返回新的IEnumerable实例,导致自定义集合的业务规则(如数据验证)在链式调用中丢失。

  • IEnumerable本质上是只读遍历协议,不提供集合修改能力
  • 手动实现完整IList需要重写超过20个成员,极易遗漏关键方法
  • WPF/WinForms数据绑定机制依赖INotifyCollectionChanged接口,仅实现IEnumerable会导致UI无法自动更新

利用Collection基类快速构建业务集合

Collection是.NET框架专门为自定义集合开发设计的可扩展基类。其核心优势在于:

它将所有集合操作拆分为独立的可重写虚方法:InsertItemRemoveItemSetItemClearItems。开发者只需重写需要添加业务逻辑的方法,其余功能由基类自动处理。

以下示例展示如何创建“仅接受正整数”的自定义集合:

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并实现IEnumerableIReadOnlyList接口。这一设计决策对集合行为有重要影响,应在项目初期明确需求。

来源:https://www.php.cn/faq/2316950.html
免责声明: 游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关攻略

c#如何调用WebAPI_c#WebAPI的最佳实践与常见坑点
编程语言
c#如何调用WebAPI_c#WebAPI的最佳实践与常见坑点

C 调用WebAPI的最佳实践与常见坑点 在微服务架构盛行的今天,通过HttpClient调用WebAPI几乎是每个C 开发者的日常。然而,从简单的GET请求到高并发下的稳定通信,中间隔着一系列容易踩坑的细节。下面我们就来梳理几个关键的最佳实践和那些容易让人栽跟头的“坑点”。 HttpClient

热心网友
04.14
c#如何定义变量_c#定义变量的几种常见方法
编程语言
c#如何定义变量_c#定义变量的几种常见方法

C 变量定义:避开那些“看似简单”的坑 显式声明变量必须写明类型 在C 编程中,一个必须遵守的基本原则是:除非使用 var 关键字,否则必须明确指定变量的数据类型。编译器不会进行自动类型猜测。例如,int count = 0;、string name = null; 或 List numbers =

热心网友
04.14
小米 Watch Type-C 充电底座发布:支持磁力吸附、智能芯片调控,39 元
科技数码
小米 Watch Type-C 充电底座发布:支持磁力吸附、智能芯片调控,39 元

小米 Watch Type-C 充电底座发布:支持磁力吸附、智能芯片调控,39 元 旅行时,谁还想为智能手表再多带一根专属充电线?这恐怕是不少用户共同的心声。就在今天,小米集团手机部副总裁、可穿戴部总经理张雷发文回应了这个问题。他提到,团队认真听取了去年米粉座谈会上的用户建议,如今,一个更便携的解决

热心网友
03.31
C#中Parallel.For与普通for循环的5个关键差异解析
科技数码
C#中Parallel.For与普通for循环的5个关键差异解析

循环是一种基本的编程结构,用于迭代处理数组、集合或其他数据结构中的元素。其中,for循环是最常见的一种,但随着多核处理器的普及,在 NET 4中新增的抽象线程类Parallel。Parallel F

热心网友
03.16
揭秘C#命令模式:核心原理与实战应用案例详解
科技数码
揭秘C#命令模式:核心原理与实战应用案例详解

在C 中,命令模式通过促进对象之间的解耦,有助于构建更加模块化、灵活和可维护的代码库。 命令模式是一种行为设计模式,它将请求转化为独立对象,封装了与请求相关的所有信息。此对象能够灵活应对不同的请求,

热心网友
02.27

最新APP

宝宝过生日
宝宝过生日
应用辅助 04-07
台球世界
台球世界
体育竞技 04-07
解绳子
解绳子
休闲益智 04-07
骑兵冲突
骑兵冲突
棋牌策略 04-07
三国真龙传
三国真龙传
角色扮演 04-07

热门推荐

《七界梦谭》长戟刚鬣boss打法攻略
游戏攻略
《七界梦谭》长戟刚鬣boss打法攻略

七界梦谭长戟刚鬣boss怎么打?全面打法机制解析 在《七界梦谭》中,即将登场的精英首领“长戟刚鬣”以其独特的造型与高难度的战斗机制,成为了众多玩家关注的焦点。它通体呈现深邃的黑色,外形轮廓融合了刺猬般的刚刺与修长的尾部,移动时带有鼠类特有的迅捷与灵动。其名“刚鬣”源于古语,精准地描述了它颈背部如刀锋

热心网友
04.15
王者荣耀世界pk模式怎么玩-王者荣耀世界pk模式玩法全解析
游戏资讯
王者荣耀世界pk模式怎么玩-王者荣耀世界pk模式玩法全解析

王者荣耀世界的 pk 模式是玩家展现实力、与各路高手激烈对抗的舞台 想体验更自由、更开放的竞技快感吗?王者荣耀的PK模式,正是这样一个让你与各路高手一决高下的舞台。在这里,战斗的规则更灵活,策略的博弈也更直接,能带来与常规对战截然不同的竞技乐趣。 参与条件 参与门槛并不复杂:当玩家等级达到要求,并且

热心网友
04.15
我在AI
AI
我在AI

我在AI是什么 简单来说,“我在AI”是一款来自南京有零科技的免费人工智能应用。它的核心思路挺有意思:不再提供单一的聊天机器人,而是打造了一个多元化的“智能体”生态。用户可以根据自己的喜好,选择不同性格、设定的人设进行互动,相当于把选择权交给了用户,让AI服务于更个性化的生活场景。 我在AI的主要功

热心网友
04.15
张雪机车LOGO陷抄袭国外品牌标识争议 真相藏不住了
业界动态
张雪机车LOGO陷抄袭国外品牌标识争议 真相藏不住了

张雪机车LOGO陷抄袭争议:一场关于“原创”的舆论风波 最近几天,机车圈里有点热闹。一组对比图在网络上流传开来,把张雪车品牌的LOGO和国外一个已有标识放在了一起。仔细一看,二者在图形结构、线条走势,乃至整体轮廓上,确实有着高度的相似性,差别似乎只存在于一些微小的细节处理上。 这事儿之所以迅速发酵,

热心网友
04.15
mysql报Server selection timeout怎么办_排查负载均衡器配置与节点存活检查
数据库
mysql报Server selection timeout怎么办_排查负载均衡器配置与节点存活检查

MySQL连接报Server selection timeout怎么办?排查负载均衡器配置与节点存活检查 首先需要明确一个核心概念:Server selection timeout这一错误信息,本质上是MongoDB驱动层抛出的异常,与MySQL服务自身的运行状态并无直接关联。它通常出现在错误混用M

热心网友
04.15