最佳实践 – 从C#中的generics集合中删除项目

我在Visual Studio 2008中使用C#和.NET 3.5。

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

private static Dictionary<EventType, List> _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); } 

我有两个问题。

首先,请注意选项1在删除项目之前检查是否存在,而选项2使用powershell删除,因为Remove()不会抛出exception。 在这两个中,这是首选的“最佳实践”方式吗?

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

谢谢。

编辑

为了澄清,我意识到选项1和2之间的选择是速度(选项2)与可维护性(选项1)的选择。 在这种特殊情况下,我不一定会尝试优化代码,尽管这肯定是值得考虑的。 我想要了解的是,如果这样做有一个普遍成熟的做法。 如果没有,您将在自己的代码中使用哪个选项?

选项1将比选项2慢.Lambda表达式和LINQ将更慢。 我会使用HashSet<>而不是List<>

如果您需要有关项目删除的确认,则必须使用Contains

编辑:由于在lock语句中使用代码的概率很高,并且最佳做法是减少lock内部的执行时间,因此应用选项2可能很有用。看起来没有最佳实践可以使用或不使用 -使用Contains Remove

Remove()方法’approches O(1)’并且当一个键不存在时是OK。

但除此之外:如果有疑问,请测量。 获得一些时间并不困难……

当你所关心的只是值时,为什么要枚举键?

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

也就是说,Eric P建议的LINQ解决方案肯定更简洁。 但是,性能可能是一个问题。

我会选择第二种选择。 Contains()和Remove()都是O(n)方法,并且没有理由同时调用它们,因为Remove不会抛出。 至少在方法2中,您只需要调用一个昂贵的操作而不是两个操作。

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

如果你想使用Linq来做这件事,我认为这样可行(未经测试):

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

可能想检查一下那个表现。