I've been working with dictionaries typed to my custom class, and then key them off an external value. For better encapsulation, I'd like to use one of the properties of the class as the key value. Is there a simple way to do this without creating a custom implementation of the dictionary?
example:
public class MyStuff{
public int num{get;set;}
public string val1{get;set;}
public string val2{get;set;}
}
var dic = new Dictionary<int, MyStuff>();
Is there some option resembling this instead? -
var dic = new Dictionary<x=> x.num, MyStuff>();
I think you're looking for KeyedCollection<TKey, TItem>
Unlike dictionaries, an element of
KeyedCollection<TKey, TItem>
is not a key/value pair; instead, the entire element is the value and the key is embedded within the value. For example, an element of a collection derived fromKeyedCollection<String,String>
(KeyedCollection(Of String, String)
in Visual Basic) might be "John Doe Jr." where the value is "John Doe Jr." and the key is "Doe"; or a collection of employee records containing integer keys could be derived fromKeyedCollection<int,Employee>
. The abstractGetKeyForItem
method extracts the key from the element.
You could easily create a derived class which implements GetKeyForItem
via a delegate:
public class ProjectedKeyCollection<TKey, TItem> : KeyedCollection<TKey, TItem>
{
private readonly Func<TItem, TKey> keySelector;
public ProjectedKeyCollection(Func<TItem, TKey> keySelector)
{
this.keySelector = keySelector;
}
protected override TKey GetKeyForItem(TItem item)
{
return keySelector(item);
}
}
Then:
var dictionary = new ProjectedKeyCollection<int, MyStuff>(x => x.num);
See more on this question at Stackoverflow