如何创建按类型去重的类HashSet数据结构并简化C#代码?
按类型去重的集合实现优化方案
你当前通过遍历列表判断类型是否存在的方式,时间复杂度为O(n),当集合元素较多时效率会明显下降。最优实现方式是借助HashSet<Type>来跟踪已添加的类型,将类型存在性判断的复杂度降到O(1),同时用组合而非继承的方式封装逻辑,避免继承List<T>带来的潜在问题。
优化后的实现代码
public abstract class Foo {} public class FooA : Foo {} public class FooB : Foo {} public class TypeUniqueFooCollection { // 存储实际元素的列表 private readonly List<Foo> _items = new List<Foo>(); // 跟踪已存在的类型,确保去重 private readonly HashSet<Type> _registeredTypes = new HashSet<Type>(); public void Add(Foo fooItem) { if (fooItem == null) throw new ArgumentNullException(nameof(fooItem)); var itemType = fooItem.GetType(); // HashSet.Add会返回是否成功添加(类型不存在时添加并返回true) if (_registeredTypes.Add(itemType)) { _items.Add(fooItem); } } // 支持foreach遍历 public IEnumerator<Foo> GetEnumerator() { return _items.GetEnumerator(); } // 按需暴露常用属性和方法 public int Count => _items.Count; // 按类型移除元素 public bool Remove(Type targetType) { if (_registeredTypes.Remove(targetType)) { var item = _items.FirstOrDefault(x => x.GetType() == targetType); return item != null && _items.Remove(item); } return false; } }
使用示例
FooA fooA = new FooA(); FooB fooB = new FooB(); FooB anotherFooB = new FooB(); var collection = new TypeUniqueFooCollection(); collection.Add(fooA); collection.Add(fooB); collection.Add(anotherFooB); foreach(var item in collection) { Console.WriteLine(item.GetType().Name); } /* 输出结果: FooA FooB */
方案优势
- 高效性:
HashSet<Type>的存在性判断是O(1)操作,远优于遍历列表的O(n),集合越大性能提升越明显 - 安全性:采用组合而非继承
List<Foo>的方式,避免了误调用基类未被覆盖的方法(如AddRange)导致的去重逻辑失效 - 灵活性:可以根据需求选择性暴露方法和属性,精准控制集合的行为边界
内容的提问来源于stack exchange,提问作者Be4Die
相关产品推荐
相关产品推荐

