Okay, so if I override Equals, I need to override GetHashCode and vice versa.
But I just wonder: Should I always override these two in any class? Especially if I know that I will use them in a Dictionary or similar collections? While this is fairly straight forward, it's still an extra work for every class.
Is the System.Object implementation bad enough to worry about this?
Edit: Can you detail a bit more what is Value and Reference equality? So if I have two strings (s1 and s2) that are both "test", they are value equal, but since they are two different strings, they are not reference-equal? Ok, for strings it's a no-brainer, but what are the common situations where you would want Reference or Value Equality?
As far as I'm aware you only need to override them if you need value equality semantics. The System.Object implementation isn't 'bad', it just only does a reference check (which is all an implementation at that level can do).
In short: If you need some sort of value based equality (equality based on properties of the class), then yes, override away. Otherwise, it should be more than fine already.
EDIT:
You only need to override them in the case above. If you override one, you do need to override both for the obvious reasons (they need to be consistent, etc). You can override them on every class for other reasons noted in other answers (like performance in algorithms that use the hash value, ie. Dictionary
keys, etc), but you don't need to, the default System.Object
implementation will work correctly.
EDIT 2: More information requested, so here goes. Consider the following pseudo-class:
public class User {
private int _id;
private string _username;
public string Username { get {return _username;}};
// [snip] Whatever other properties we might like to have.
public User(string username) {
// Initialise our user from a database, or whatever.
}
}
As it stands, the following code, might seem intuitive:
User foo = new User("me");
User bar = new User("me");
User baz = foo;
if (foo.Equals(bar)) {
Console.WriteLine("1: Success!");
}
if (foo.Equals(baz)) {
Console.WriteLine("2: Success!");
}
But it will only print out:
2: Success
Why? foo
and bar
are two seperate instances of the class, and have separate references. A reference is like a pointer in C/C++. foo and baz are the same reference because one was assigned from the other. They all have the same value though, the user called "me". A sample implementation of a value based .Equals
implementation might be:
partial class User {
public override bool Equals(object b) {
if (b == null) return false;
if (b.GetType() != this.GetType()) return false;
// Now the heavy lifting
User other = (User)b;
if (other._id == this._id) return true;
else return false;
}
}
See how it checks against part of the class's properties to determine equality? That's value equality at work. Reference equality would just be a simple this == b
check.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With