【问题标题】:Dictionary Keys.Contains vs. ContainsKey: are they functionally equivalent?Dictionary Keys.Contains 与 ContainsKey:它们在功能上是否等效?
【发布时间】:2011-11-23 00:27:32
【问题描述】:

我很想知道这两者在所有情况下是否在功能上都是等效的。

是否有可能通过更改字典的默认比较器,这两者在功能上会有所不同?

另外,Keys.Contains 不是几乎可以保证更慢吗?

【问题讨论】:

    标签: c# performance dictionary equivalence


    【解决方案1】:

    这两个函数做的事情完全一样。

    Keys.Contains 存在是因为Keys 是一个ICollection<TKey>,它定义了一个Contains 方法。
    标准的Dictionary<TKey, TValue>.KeyCollection 实现(类,而不是接口)将其定义为

    bool ICollection<TKey>.Contains(TKey item){ 
        return dictionary.ContainsKey(item); 
    }
    

    由于它是显式实现的,你甚至不能直接调用它。


    您看到的不是我上面解释的接口,就是 LINQ Contains() 扩展方法,它也将调用本机实现,因为它实现了ICollection&lt;T&gt;

    【讨论】:

    • @ReedCopsey:不,不会更慢;我检查了来源。此外,如果您的字典引用的编译时类型是接口,它将调用ICollection&lt;TKey&gt;.Contains,而不是 LINQ 方法。
    • 我现在看到我确实在调用扩展方法。
    • 唯一可以避免使用 LINQ 方法的方法是,如果您使用 IDictionary&lt;T,U&gt;,而不是 Dictionary&lt;T,U&gt; 作为变量,虽然......对吧?
    • @mhand:这两点都错了。 Enumerable.ContainsKeyCollection 上是 O(1),重载决议将更喜欢实例方法而不是扩展方法。 referencesource.microsoft.com/#System.Core/System/Linq/…
    • @mhand:是的,IDictionary&lt;K, V&gt;.Keys 是一个ICollection&lt;K&gt;
    【解决方案2】:

    虽然它们与Dictionary&lt;,&gt; 相当,但我发现坚持使用ContainsKey() 更安全。

    原因是将来您可能决定使用ConcurrentDictionary&lt;,&gt;(使您的代码线程安全),并且在该实现中,ContainsKey 明显更快(因为访问Keys 属性确实一堆锁定并创建一个新集合)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-20
      • 2011-01-26
      • 2011-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多