Let’s say I have a simple class Cat in C#, with a Name property of type string. Now I need a collection class for my cats, so I decide to wrap a Dictionary<string, Cat> in a custom collection class. Basically, this class holds a private dictionary variable and adds or removes collection members as necessary, as well as indexing cats by their name:
class Cats
{
private Dictionary<string, Cat> m_dic = new Dictionary<string,Cat>();
public void Add(Cat c)
{
m_dic.Add(c.Name, c);
}
public void Remove(string name)
{
m_dic.Remove(name);
}
public Cat this[string name]
{
get
{
return m_dic[name];
}
}
}
Now I can create a collection and cats to it, like this:
Cats cs = new Cats();
cs.Add(new Cat("Valentina"));
cs.Add(new Cat("Sophie"));
cs.Add(new Cat("Tomboy"));
And I can retrieve a cat from its name:
Cat c1 = cs["Sophie"];
All this is very good. The problem is, when I change the name of a cat, like this:
c1.Name = "Sofia";
…the collection key for the object referred to by c1 is not updated, evidently. So, if I try to retrieve the same item using its new name, I get an exception:
Cat c2 = cs["Sofia"]; //KeyNotFoundException is thrown here.
This is correct and obvious behavior by the runtime. My question is: can you suggest an elegant and reliable method to alter the collection keys whenever the name property of an element changes?
My objective is to be able to retrieve, at any time, an item from its name, as you can imagine. I have approached the problem by having the setter of the Name property raise an event so that any collection holding that object can update the corresponding key. This method is quite cumbersome and not very efficient, though.
Can you think of anything better? Thank you.
How large is your collection going to be, and how important is being able to retrieve an item through an index?
If it’s going to be relatively small (several hundred, as opposed to thousands), you might be better off using a
List<Cat>, and access them using the new LINQ extension methods, like:Adding (and deleting) is also trivial:
Let me know if this will not work for you. Hope this helps!