必须用List和Dictionary而非ArrayList或Hashtable,因泛型集合提供编译期类型检查、避免装箱、消除强制转换;自定义键需实现IEqualityComparer或重写GetHashCode/Equals;初始化推荐new List<T>()或[],查字典用TryGetValue,遍历时删除需用RemoveAll或反向for。

直接用 List<t></t> 和 Dictionary<tkey tvalue></tkey>,别碰 ArrayList 或 Hashtable —— 它们不是“不能用”,而是编译期不检查类型、运行时才报错,徒增调试成本。
为什么必须用 List<t></t> 而不是 ArrayList
ArrayList 存什么都能过编译,取出来还得手动 (int) 强转,一不小心就 InvalidCastException;List<t></t> 在声明时就锁死类型,编译器直接拦住非法操作。
-
List<int></int>只接受int,加"abc"会红波浪线 + 编译错误 - 从
List<string></string>取元素不用 cast,直接当string用 - 值类型(如
int)存进ArrayList会装箱,频繁操作有性能损耗;List<int></int>避免装箱
Dictionary<string int></string> 的键必须可比较,且不能为 null(引用类型)
当你用自定义类做键,比如 Dictionary<person decimal></person>,默认行为是按引用比较 —— 两个内容相同但不同实例的 Person 会被当成不同键。这通常不是你想要的。
- 解决方法:让
Person实现IEqualityComparer<person></person>,或重写GetHashCode()和Equals() - 如果键是
string,它本身已实现比较逻辑,直接用即可 - 注意:
Dictionary不允许null键(除非 TKey 是可空引用类型,如string?,且启用了 nullable context)
泛型集合初始化和常见误操作
初始化写法影响可读性和 null 安全性,尤其在 .NET 6+ 启用 nullable reference types 后。
- 推荐写法:
var list = new List<string>();</string>或List<string> list = [];</string>(C# 12 空集合字面量) - 避免
List<string> list = null;</string>后再list.Add(...)—— 直接NullReferenceException -
Dictionary查不存在的键会抛KeyNotFoundException,要用TryGetValue()而不是先ContainsKey()再取值(多一次查找) - 不要用
foreach循环中调用Remove()—— 会触发InvalidOperationException: Collection was modified;改用list.RemoveAll(x => x > 10)或反向for循环
泛型集合真正的坑不在语法,而在「什么时候该加约束」—— 比如你写了个泛型方法要对 T 排序,却忘了加 where T : IComparable<t></t>,编译器不会立刻报错,直到你传入一个没实现该接口的类型才崩。这种延迟暴露的问题,比类型不匹配更难定位。


















