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 key开发者_高级运维s 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());
}
}
}
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.
Not sure this is the most efficient but you could use the Dictionary property to retrieve the generic dictionary representation and then use the the Keys property on that to get the list of keys.
精彩评论