C# collection indexed by property?

I'm not sure if there's anything built-in that does what you want, but there's nothing stopping you from wrapping a dictionary specifying the key yourself, and implementing IList<Person>. The key here (no pun intended) is the consumer does not has access to the underlying dictionary so you can be assured the keys are accurate.

Part of the implementation might look like the following, note the custom indexer as well:

public partial class PersonCollection : IList<Person>
{

    //the underlying dictionary
    private Dictionary<string, Person> _dictionary;

    public PersonCollection()
    {
        _dictionary = new Dictionary<string, Person>();
    }

    public void Add(Person p)
    {
        _dictionary.Add(p.Name, p);
    }

    public Person this[string name]
    {
        get
        {
            return _dictionary[name];
        }
    }

}

As a side bonus, you are also free to change the implementation later without having to change the consuming code.


You can build your own collection backed by a dictionary to accomplish this task. The idea is to store a delegate that takes a Person and returns a string by reading the Name property.

Here is a skeletal solution of such a collection:

public class PropertyMap<K,V> : ICollection<V> {
    private readonly IDictionary<K,V> dict = new Dictionary<K,V>();
    private readonly Func<V,K> key;
    public PropertyMap(Func<V,K> key) {
        this.key = key;
    }
    public void Add(V v) {
        dict.Add(key(v));
    }
    // Implement other methods of ICollection
    public this[K k] {
        get { return dict[k]; }
        set { dict[k] = value; }
    }
}

Here is how to use it:

PropertyMap<string,Person> mp = new PropertyMap<string,Person>(
    p => p.Name
);
mp.Add(p1);
mp.Add(p2);