当前位置: 首页 > news >正文

C# 集合详解:ArrayList 与 List<T>的核心用法与对比

一、C# 集合体系概览

C# 的集合类型主要分布在两个核心命名空间:

  • System.Collections:非泛型集合,适用于.NET 早期版本,代表类型有ArrayListHashtableQueue等;
  • System.Collections.Generic:泛型集合(.NET 2.0+),类型安全且性能更优,代表类型有List<T>Dictionary<TKey, TValue>HashSet<T>等。

其中,ArrayListList<T>作为动态数组的典型实现,是日常开发中最常用的集合类型,也是理解 C# 集合设计思想的关键。

二、ArrayList:非泛型动态数组

2.1 ArrayList 核心特性

ArrayList是 C# 早期的动态数组实现,本质是封装了object[]数组的类,核心特性如下:

  • 动态扩容:底层基于数组实现,初始容量为 0,添加第一个元素时扩容至 4,后续自动按需扩容;
  • 非类型安全:所有元素均以object类型存储,值类型会发生装箱 / 拆箱操作;
  • 灵活存储:允许存储null值、重复元素,支持任意类型的对象;
  • 索引访问:支持数组式的索引器访问,时间复杂度 O (1)。

2.2 ArrayList 常用操作

1. 初始化

ArrayList提供三种初始化方式,适配不同场景:

// 空列表(初始容量0) ArrayList list1 = new ArrayList(); // 指定初始容量(减少扩容次数,提升性能) ArrayList list2 = new ArrayList(100); // 从其他集合初始化 ArrayList list3 = new ArrayList(new int[] { 1, 2, 3 });
2. 元素增删

ArrayList提供丰富的元素操作方法,覆盖单个 / 批量、尾部 / 指定位置的增删需求:

ArrayList list = new ArrayList(); // 1. 添加元素 list.Add("C#"); // 尾部添加单个元素 list.Add(123); // 值类型自动装箱(int → object) list.AddRange(new object[] { 4.5, DateTime.Now }); // 批量添加 list.Insert(1, "插入到索引1的位置"); // 指定索引插入 list.InsertRange(2, new ArrayList { "a", "b" }); // 批量插入 // 2. 删除元素 list.Remove("C#"); // 按值删除第一个匹配项 list.RemoveAt(0); // 按索引删除 list.RemoveRange(1, 2); // 从索引1开始删除2个元素 list.Clear(); // 清空所有元素
3. 元素查找与访问
ArrayList list = new ArrayList { "A", "B", "C", "B" }; // 检查元素是否存在 bool hasB = list.Contains("B"); // true // 查找元素索引 int firstBIndex = list.IndexOf("B"); // 1 int lastBIndex = list.LastIndexOf("B"); // 3 // 索引器访问(需显式类型转换) string item = (string)list[0]; // "A" // 排序后二分查找(需先Sort) list.Sort(); int cIndex = list.BinarySearch("C"); // 2

2.3 ArrayList 的局限性

尽管ArrayList灵活,但存在明显短板:

  • 性能损耗:值类型的装箱 / 拆箱操作增加内存开销和性能消耗;
  • 类型不安全:编译时无法校验元素类型,运行时可能抛出InvalidCastException
  • 现代开发不推荐:仅适用于遗留代码或.NET 1.x 环境,新代码优先使用泛型集合。

三、List<T>:类型安全的泛型动态数组

List<T>ArrayList的泛型替代版本,解决了非泛型集合的类型安全和性能问题,是当前 C# 开发的首选动态数组。

3.1 List<T>核心优势

ArrayList相比,List<T>的核心改进在于:

特性ArrayListList<T>
类型安全非泛型,object 存储泛型,编译时类型校验
性能装箱 / 拆箱损耗无装箱操作,性能更优
内存占用较高(object 引用)更低(直接存储值类型)
错误排查运行时类型转换异常编译时类型错误提示

3.2 List<T>常用操作

1. 初始化与基础操作

// 空列表 List<int> numbers = new List<int>(); // 初始化赋值 List<string> names = new List<string> { "Alice", "Bob" }; // 指定初始容量 List<double> values = new List<double>(10); // 添加元素 numbers.Add(1); numbers.AddRange(new int[] { 2, 3, 4 }); // 访问与修改 int first = numbers[0]; // 无需拆箱 numbers[1] = 10; // 基础查询 int count = numbers.Count; bool has3 = numbers.Contains(3);

2. 高级操作:排序

List<T>Sort方法支持多种排序方式,满足复杂场景需求:

方式 1:默认排序(实现 IComparable<T>)

自定义类型需实现IComparable<T>接口,重写CompareTo方法:

public class Student : IComparable<Student> { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } // 按Id升序排序 public int CompareTo(Student other) { if (this.Id > other.Id) return 1; if (this.Id < other.Id) return -1; return 0; } } // 排序使用 List<Student> students = new List<Student> { new Student { Id = 1, Name = "张三" }, new Student { Id = 3, Name = "李四" }, new Student { Id = 2, Name = "王五" } }; students.Sort(); // 按Id升序排列
方式 2:自定义比较器(IComparer<T>)

适用于多种排序规则的场景,无需修改实体类:

// 按年龄降序的比较器 public class StudentAgeComparer : IComparer<Student> { public int Compare(Student x, Student y) { return y.Age.CompareTo(x.Age); } } // 使用比较器排序 students.Sort(new StudentAgeComparer());
方式 3:Lambda 表达式(Comparison<T>)

适用于临时排序需求,简化代码:

// 按年龄降序排序 students.Sort((x, y) => y.Age.CompareTo(x.Age));

3. 高级操作:查找与转换

List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; // 查找第一个偶数 int firstEven = numbers.Find(n => n % 2 == 0); // 查找所有偶数 List<int> allEvens = numbers.FindAll(n => n % 2 == 0); // 转换为字符串列表 List<string> strNumbers = numbers.ConvertAll(n => n.ToString()); // 转换为数组 int[] numArray = numbers.ToArray();

四、ArrayList 与 List<T>核心对比

表格

维度ArrayListList<T>
类型系统非泛型(object)泛型(强类型)
性能装箱 / 拆箱损耗无装箱,性能更高
类型安全运行时可能出错编译时类型校验
内存占用较高更低
适用场景遗留代码、混合类型存储现代开发、类型明确的集合
引入版本.NET 1.0.NET 2.0+

五、最佳实践

  1. 优先使用 List<T>:新开发项目中,无论值类型还是引用类型,均推荐使用List<T>,兼顾性能与类型安全;
  2. 避免 ArrayList:仅在维护.NET 1.x 遗留代码或必须存储混合类型时使用ArrayList
  3. 指定初始容量:当已知集合大致大小,初始化时指定容量(如new List<int>(100)),减少自动扩容的性能损耗;
  4. 排序优化:自定义类型排序优先使用IComparer<T>Comparison<T>,避免修改实体类的IComparable<T>实现;
  5. 减少装箱操作:若需存储混合类型,可使用List<object>替代ArrayList,保持泛型特性。

总结

ArrayList作为 C# 早期的动态数组实现,见证了.NET 集合体系的发展;而List<T>作为泛型时代的产物,凭借类型安全、高性能的优势成为现代 C# 开发的首选。理解两者的设计思想与使用差异,不仅能帮助开发者写出更高效的代码,也能深入掌握 C# 类型系统的核心逻辑。在实际开发中,结合场景选择合适的集合类型,才能充分发挥 C# 的语言特性与性能优势。

http://www.gsyq.cn/news/1376143.html

相关文章:

  • 数据驱动VS物理模型:随机森林在电动汽车跟驰行为预测中的精度革命
  • 频率学习模型:基于傅里叶思想的参数高效神经网络架构
  • 工业设备预测性维护实战:自适应阈值与合成数据驱动的故障诊断
  • Armv9 SME指令集:矩阵运算加速原理与优化实践
  • SubCube稀疏注意力架构的优势是什么
  • vi与vim在openEuler中的差异及应用
  • RAG 架构在网文创作中的应用:以茄子写作助手为例
  • Token经济学正在重构芯片工程师的生存逻辑(万字长文深度拆解“token“这个计量单位的对于芯片工程师的意义)
  • 深度学习新手必懂的激活函数!Sigmoid、Tanh、ReLU、Leaky ReLU、Softmax 详解
  • 助睿实验作业3-学生用户画像考勤主题扩展标签构建
  • 直接去偏机器学习:用Bregman散度统一因果推断与协变量平衡
  • Windows Audio服务启动失败?除了疑难解答,你还需要检查这些容易被忽略的设置
  • 基于CNN的遥感影像土地利用分类:从原理到斐济城市扩张监测实践
  • 嘉兴GEO优化公司2026年度深度评测选型指南 - 品牌报告
  • 字节校招7000人转正率50%:大厂HR体系,正在“去经验化“
  • 避坑指南:在openEuler 22.03上配置vsftpd虚拟用户,解决gdbm数据库和SELinux权限问题
  • IwaraDownloadTool:简单快速的Iwara视频下载神器
  • 2026趋势:大学生如何借助 GPT-5.5 完成课题研究和写作(附伦理提示)
  • 华硕笔记本终极性能优化:用G-Helper替代Armoury Crate的完整指南
  • 苏州评价高的宠物基地口碑推荐榜单 - 品牌排行榜
  • Python Pickle安全新方案:基于源码分析的机器学习模型安全加载实践
  • 免费获取百度网盘真实下载地址的终极解决方案
  • 机器学习预测全球预期寿命:线性回归、决策树与随机森林模型对比
  • 2024终极指南:如何用微信红包助手快速抢到所有红包
  • JMeter压测8大实战陷阱:从线程模型到SLA验证
  • 安卓乐享云 不限速磁力下载神器 60T空间 边下边播
  • C166微控制器复位向量重定位技术详解
  • 如何3分钟配置智慧树自动刷课插件:终极高效学习解决方案
  • 别再只装LibreOffice了!离线安装后,这3个配置让你的文档体验飙升(CentOS/Ubuntu通用)
  • QClaw小龙虾的下载、安装和使用