4

Suppose:

Dictionary<Guid, MyClass> dict;

Is there any difference between

dict.Keys.Contains(key)

and

dict.ContainsKey(key)

I thought there was no difference, but I am not sure now.

Hong
  • 17,643
  • 21
  • 81
  • 142
  • right, I didn't notice `Contains` is implemented differently in KeyCollection. by the way first approach create an extra reference for KeyCollection, you shouldn't bother but IMO only use `Keys` property when you actually need it. – M.kazem Akhgary Sep 03 '17 at 22:49
  • Either method should be used sparingly. A good proportion of the time you think you need to use it (i.e. when you want to know whether the key exists, and what the value is **for** that key), you should likely use `TryGetValue` instead. – mjwills Sep 03 '17 at 23:08

3 Answers3

8

These two methods are guaranteed to return the same true/false value.

According to reference implementation, dict.Keys.Contains(key) delegates to dict.ContainsKey(key):

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

This method is part of KeyCollection class. Its dictionary field refers to the Dictionary object that owns the KeyCollection returned by Keys property.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
2

The first line retrieves the keys collection before searching for the key, while the second line searches the dictionary's keys directly avoiding an extra step.

According to the documentation for the Dictionary.Keys property, accessing the collection is a constant time operation and does not involve creating a copy of the entire set of dictionary keys. Thus there appears to be little difference between the two operations aside from the additional step of retrieving the keys collection before searching for the key.

All things being equal, I would personally prefer the second version because it skips the extra step and conveys your intent more concisely.

v1bri
  • 1,398
  • 8
  • 13
1

A Dictionary is optimized for looking up keys.

With dict.ContainsKey(key) you would be sure to use that optimized search.

When you use dict.Keys.Contains(key) you are more dependent on the implementation. The naive route would first get an IEnumerable<TKey> and then do the (linear) lookup. The actual library class might be smarter but you would always have to look up the source to be sure.

H H
  • 263,252
  • 30
  • 330
  • 514
  • 2
    It explicitly states [in the documentation](https://msdn.microsoft.com/en-us/library/mt481488(v=vs.110).aspx) *"This method is an O(1) operation."* so there is no need to fear of a naive implementation, it is documented. – Scott Chamberlain Sep 03 '17 at 22:51
  • Yes, but that's just one implementation. I couldn't find the same statement for SortedDictionary for example. – H H Sep 04 '17 at 05:40