I have an Address class in C# that looks like this:
public class Address
{
public string StreetAddress { get; set; }
public string RuralRoute { get; set; }
public string City { get; set; }
public string Province { get; set; }
public string Country { get; set; }
public string PostalCode { get; set; }
}
I'm implementing equality and so I need to override the hash code. At first I was going to use the hashcode formula from EJ but then I thought: These are all string fields, can't I just just use a StringBuilder to concatenate them and return the hash code from that string?
That is:
var str = new StringBuilder();
str.Append(StreetAddress)
.Append(RuralRoute)
...
return str.ToString().GetHashCode();
What are the advantages/disadvantages of this? Why shouldn't I do it?
For this sort of thing, you might want to implement
IEqualityComparer<Address>
:You could also implement
IComparable<Address>
to get ordering...I would avoid doing that simply on the grounds that it creates a bunch of strings pointlessly - although Kosi2801's point about making collisions simple is also relevant. (I suspect it wouldn't actually create many collisions, due to the nature of the fields, but...)
I would go for the "simple and easy to get right" algorithm I've previously used in this answer (thanks for looking it up lance :) - and which is listed in Effective Java, as you said. In this case it would end up as:
That's not null-safe, of course. If you're using C# 3 you might want to consider an extension method:
Then you can use:
You could create a parameter array method utility to make this even simpler:
and call it with:
In most types there are primitives involved, so that would perform boxing somewhat unnecessarily, but in this case you'd only have references. Of course, you'd end up creating an array unnecessarily, but you know what they say about premature optimization...
Don't do that because the objects can be different altough the hashcode is the same.
Think of
vs
Both will have the same hashcode but different content in the fields.