Search code examples
c#data-structuresdictionaryhashtablekeyedcollection

What is the most efficient way to obtain the list of keys from a KeyedCollection?


I am looking for a way that is as efficient as the Keys property (of type KeyCollection) of a generic dictionary.

Using a Linq select statement would work, but it would iterate over the whole collection each time the keys are requested, while I believe the keys may already be stored internally.

Currently my GenericKeyedCollection class looks like this:

public class GenericKeyedCollection<TKey, TItem> : KeyedCollection<TKey, TItem> {
    private Func<TItem, TKey> getKeyFunc;

    protected override TKey GetKeyForItem(TItem item) {
        return getKeyFunc(item);
    }

    public GenericKeyedCollection(Func<TItem, TKey> getKeyFunc) {
        this.getKeyFunc = getKeyFunc;
    }

    public List<TKey> Keys {
        get {
            return this.Select(i => this.GetKeyForItem(i)).ToList();
        }
    }
}

Update: Thanks to your answers, I will therefore use the following property instead of iterating with Linq.

    public ICollection<TKey> Keys {
        get {
            if (this.Dictionary != null) {
                return this.Dictionary.Keys;
            }
            else {
                return new Collection<TKey>(this.Select(this.GetKeyForItem).ToArray());
            }
        }
    }

Solution

  • As per the documentation, the class has a property, Dictionary, so you can do this:

    var keys = collection.Dictionary.Keys;
    

    Note that there is a caveat, as described in the documentation. If you construct the collection with a threshold value for the dictionary, the dictionary will not be populated until at least that many values has been put into the collection.

    If this is not the case for your situation, ie. the dictionary is always good to go, the above code should do the trick.

    If not, then you either have to change your construction to avoid setting that threshold, or you will just have to loop and extract the key through the GetKeyForItem method.