You don't need to implement it. If you write your own Equals() method I'd recommend to use some GetHashCode implementation that doesn't break HashSet though. You could for instance return a static value (typically 42). HashSet performance will degrade dramatically, but at least it will still work - you'll never know who'll use/edit/maintain your code in the future. (edit: you may want to log a warning if such a class is used in a hashed structure in order to early spot performance problems)
EDIT: don't only use XOR to combine hash codes of your properties
It has already been said by others that you may simply combine hash codes of all your properties. Instead of only using XOR I'd encourage multiplying results though. XOR may result in a 0 value if both values are equal (e.g. 0xA ^ 0xA == 0x0
). This may be easily improved using 0xA * 0xA
, 0xA * 31 + 0xA
or 0xA ^ (0xA * 31)
.
Still, the intent of my answer is that any hash function is better than one that isn't consistent with equals - even if it only returns a static value. Simply select any subset of properties (from none to all) you use for equality and throw the results together. While selecting properties for hash code, prefer those small subsets which combinations are pretty unique (e.g. firstname, lastname, birthday - no need to add the whole address)