代码之家  ›  专栏  ›  技术社区  ›  Matt Davis

最佳实践-在C中从泛型集合中删除项#

  •  3
  • Matt Davis  · 技术社区  · 16 年前

    我有一个通用字典,它将事件类型映射到订阅者的通用列表。订阅者可以订阅多个事件。

    private static Dictionary<EventType, List<ISubscriber>> _subscriptions;
    

    要从订阅列表中删除订阅服务器,我可以使用这两个选项之一。

    备选案文1:

    ISubscriber subscriber;  // defined elsewhere
    foreach (EventType event in _subscriptions.Keys) {
        if (_subscriptions[event].Contains(subscriber)) {
            _subscriptions[event].Remove(subscriber);
        }
    }
    

    备选案文2:

    ISubscriber subscriber;  // defined elsewhere
    foreach (EventType event in _subscriptions.Keys) {
        _subscriptions[event].Remove(subscriber);
    }
    

    我有两个问题。

    第二,是否有另一种“更干净”的方式来实现这一点,可能是使用lambda表达式或使用LINQ扩展?我仍在逐渐适应这两个特点。

    谢谢

    为了澄清,我意识到选项1和选项2之间的选择是速度(选项2)和可维护性(选项1)的选择。在这种情况下,我不一定要优化代码,尽管这确实是一个值得考虑的问题。我想了解的是,是否有一个普遍公认的做法来做这件事。如果没有,您会在自己的代码中使用哪个选项?

    5 回复  |  直到 12 年前
        1
  •  3
  •   LicenseQ    16 年前

    HashSet<> 而不是 List<> .

    如果您需要确认项目移除,则 Contains

    编辑: 因为在内部使用代码的概率很高 lock 包含 Remove .

        2
  •  2
  •   Pontus Gagge    16 年前

    Remove()方法“接近O(1)”,并且在键不存在时可以。

        3
  •  1
  •   Jim Mischel    16 年前

    当您只关心值时,为什么要枚举键?

    foreach (List<ISubscriber> list in _subscriptions.Values)
    {
        list.Remove(subscriber);
    }
    

        4
  •  0
  •   Reed Copsey    16 年前

    我会选择第二种选择。Contains()和Remove()都是O(n)方法,没有理由同时调用这两个方法,因为Remove不会抛出。至少对于方法2,您只调用了一个昂贵的操作,而不是两个。

    我不知道有什么更快的方法来处理它。

        5
  •  0
  •   Eric Petroelje    16 年前

    _subscriptions.Values.All(x => x.Remove(subscriber));
    

    不过,我想检查一下这方面的性能。