views:

248

answers:

1

I have quite a few dictionaries where the key is a composite of several different values (mostly strings and integers). Do I implement these keys as classes (and override GetHashCode(), Equals() etc) or do I use struct instead?

ReSharper makes it easy to do the overriding, but the code looks horrible. Are there any performance implications of using a struct instead?

+2  A: 

If your only problem is defining equality for the use in a Dictionary<TKey,TValue> then another path you may choose is implementing an IEqualityComparer<T>. This can be manually passed to the dictionary constructor and take care of equality comparisons for the TKey value without modification to the key type.

If you have the more general problem of defining equality for your composite values then I would focus on making the composite value natively support equality. Yes, defining the full set of methods necessary for equality is a pain but it's mostly boiler plate code. Getting it right is more important than whether or not the boiler plate code looks messy.

JaredPar
What I don't like is exactly that "getting it right" can be quite tricky. As an example, if I need to add a new field to the key it is extremely important that I remember to also add the field to the equality comparer/hash code etc. It might be ok as long as I'm the only one doing these things, but I won't be for long..
CodingInsomnia
@andlju, I agree getting in right is tedious and yes it requires a bit of rigor when updating a type. But I find that to be poor justification for not implementing equality. **Any** modification of a type requires you to think carefully about the contracts it holds and to do you best to maintain them. Equality is not unique in this aspect.
JaredPar
Yeah, true. So that kind of answers the question about why I still could use a class. But I'm still curious about why I should not use structs? What's the case against them?
CodingInsomnia
@andlju, I'd go more what's the case for them? In general I avoid structs unless I have a compelling reason to use them. Yes it will implement a functional equality mechanism for structs containing otherwise comparable fields. But the implementation leaves a lot to be desired. For example it does not override ==, !=, or implement `IEquatable<T>`. The last is one of the worst because it forces every comparison to include a boxing operation.
JaredPar
Thanks, that explains a lot!
CodingInsomnia