Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What Type should myCustomDictionary.Values return?

If you have the object Dictionary<k, v> myDictionary, then myDictionary.Values will be of type Dictionary<k, v>.ValueCollection and myDictionary.Keys will be of type Dictionary<k, v>.KeyCollection.

I don't understand why the type of myDictionary.Values is not something like IEnumerable<v>, IList<v> or something else.

Now, with that in mind, if I create a custom kind of dictionary; Dictionary2<k1, k2, v>, should myCustomDictionary.Values return an IEnumerable<v>, or a custom implement of ValueCollection? More importantly, why?

like image 485
Tipx Avatar asked Apr 23 '13 14:04

Tipx


2 Answers

Note that Dictionary<TKey, TValue>.ValueCollection does in fact implement ICollection<TValue> and therefore also IEnumerable<TValue>.

The reason why the property is typed the way it is is likely for performance reasons: since the methods of this class are not virtual, they can be exactly resolved during JIT compilation, instead of requiring vtable lookups for each method call at runtime. This effectively removes one level of indirection from each method you call on the collection. (It also gives the JIT the option to inline those method calls!)

Of course, you can implicitly convert the object to ICollection<TValue> if necessary, so there is no loss of functionality here, just a bit of (micro) optimization.

In your case, there is no reason you cannot return ICollection<TValue>, but you can return a more specific type if you would like. If you do, then you will have to explicitly implement the interface property IDictionary<TKey, TValue>.Values to satisfy the interface:

private ValueCollection valueCollection;

public ValueCollection Values
{
    get { return valueCollection; }
}

ICollection<TValue> IDictionary<TKey, TValue>.Values
{
    get { return valueCollection; }
}

This correctly implies that any performance benefit will only be given to consumers of the class if they are using a reference typed as your collection type; there will be no performance advantage if they take a reference to IDictionary<TKey, TValue>, as they will have to choice but to access your value collection through ICollection<TValue> anyway.

In my work, I have not found the performance difference to be significant enough to warrant returning anything more specific than ICollection<TValue>. Remember: always benchmark, and never prematurely optimize.

like image 117
cdhowie Avatar answered Sep 19 '22 03:09

cdhowie


Dictionary<k, v>.ValueCollection implements IEnumerable<v> and Dictionary<k, v>.KeyCollection implements IEnumerable<k>. It's not like the results that are returned aren't enumerable.

By returning an actual class that implements IEnumerable rather than typing the result as IEnumerable they have the ability to include a bit of additional functionality as well. For example, both collections have a Count property, which isn't easily accessible from any IEnumerable.

like image 30
Servy Avatar answered Sep 22 '22 03:09

Servy