You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建按类型去重的类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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 12:15:03