It’s happened to me a few times when I create a property of a type List<T> or Collection<T>, where T is something simple such as a string or an int, and then later I regret I’ve done so. For instance, the other day I had the following scenario (I’ve changed things around in order to make it a little simpler for this post):
I have some class that had a Parameter property of type Collection<string>:
public class SomeClass { private Collection<string> m_Parameters = new Collection<string>(); public Collection<string> Parameters { get { return m_Parameters; } set { m_Parameters = value; } } public SomeClass() { this.Parameters("A"); this.Parameters("B"); this.Parameters("C"); } }
It used to work great when all I needed was a list of parameters there:
SomeClass foo = new SomeClass(); foreach (string parameter in foo.Parameters) { Console.WriteLine(parameter); }
However, in order to support something new feature, I also needed to store the old and new values for the parameter. Hmpf. Now, instead of a Collection of strings, I need a collection of something else. I then created a Parameter class, with the specific properties I needed:
public class Parameter { public string ParameterName { get; private set; } public object OldValue { get; private set; } public object NewValue { get; private set; } public Parameter(string parameterName, object oldValue, object newValue) { ParameterName = parameterName; OldValue = oldValue; NewValue = newValue; } }
Nothing too fancy. At this point I can change my Collection<string> to Collection<Parameter>. Obviously, I’ll also have to change any code that works with that collection, since the generic type for the collection has changed:
SomeClass foo = new SomeClass(); foreach (Parameter parameter in foo.Parameters) { Console.WriteLine(parameter.ParameterName); Console.WriteLine(parameter.OldValue); Console.WriteLine(parameter.NewValue); }
If I had gone with a richer type to begin with, I wouldn’t have to change any caller of that collection; if I needed more information, all I’d have to do was to add more properties to the Parameter class. In this one case, making the change wasn’t such a big deal because my property was exposed only within the assembly; if it was exposed as a public property, than that’d be a major breaking change because I’d have no clue as to who else would be using it in other assemblies.
That makes me think whenever I’m declaring a Collection or List of something, I should put a little more thought into whether it’s likely that I’ll need some extra information associated with it, and if so, I should create a special type for it.
Also, it turns out that what I really needed was some sort of dictionary, because I wanted to look up items by a given key (in this case, the parameter’s name). The Collection<T> doesn’t give me that behavior, but the KeyedCollection<TKey, TItem> does, so I created a ParameterCollection like so:
public class ParameterCollection : KeyedCollection<string, Parameter> { protected override string GetKeyForItem(Parameter item) { return item.ParameterName; } }
The class uses a string as the key (which is the ParameterName), and the Parameter as the value. So my SomeClass class ended up like this:
public class SomeClass { private ParamaterCollection m_Parameters = new ParamaterCollection(); public ParamaterCollection Parameters { get { return m_Parameters; } set { m_Parameters = value; } } public SomeClass() { this.Parameters.Add(new Parameter("A", "A old value", "A new value")); this.Parameters.Add(new Parameter("B", "B old value", "B new value")); this.Parameters.Add(new Parameter("C", "C old value", "C new value")); } }
And besides using a regular foreach, I can also access the elements like this:
Console.WriteLine(foo.Parameters["A"].OldValue); Console.WriteLine(foo.Parameters["B"].OldValue);




Leave a Reply to ClaudioCancel reply