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?
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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With