Overriding Equals method

N

Neven Klofutar

hi,

I have some questions regarding overriding Equals method so I can use it on
my objects.

1) When overriding Equals method, do I have to check all fields for
"equality" or just the ones I want to use to distinct my objects ? As far as
I know, only the ones I want to use to distinct my object by ... field
"Name" in the example bellow.

2) What does a method GetHashCode() do exactly, and do I have to put all of
my fields in it or just fields I want to use to distinct my objects by ?

Thanx, Neven


---------------------
public class Person {

string _Name = "";
string _Phone = "";

public string Name {
get {return _Name;}
set {_Name = value;}
}
public string Phone {
get {return _Phone;}
set {_Phone = value;}
}

public override bool Equals(Object obj) {
if (obj == null || GetType() != obj.GetType()) return false;
Person person = (Person)obj;

return _Name == person.Name && _Phone == person.Phone;
}

public override int GetHashCode() {
return _Name.GetHashCode() ^ _Phone.GetHashCode();
}
}
 
C

Chris Fulstow

You can define the Equals() method in any way you like, so long as it
makes sense in the context of your objects. You might also want to
override the "==" operator.

GetHashCode() is used to determine if two objects are different when
stored in a hashed data structure, such as a hash table, so you should
probable use the same distinction criteria as your Equals() method.
 
D

Dave Sexton

Hi Neven,

Classes usually don't override Equals or GetHashCode. Structs on the other hand should always override Equals and GetHashCode, and
define the operator overloads for == and != as well.

GetHashCode is used by Hashtables to optimize the storage and access of an object used as a key and Equals is used to find the key
again. Classes don't normally need to modify this functionality. If you do modify one or the other, than you should override both
otherwise you might not be able to use your class as the key in a Hashtable.

If your class requires different semantics than what is provided by the Object.Equals method, which checks for instance equality,
then you might want to think about coding your class as a struct instead since you are associating value-type semantics to your
class anyway. But I would think about why you want to use the Equals method before implementing your class as struct because
defining a struct will place different constraints on your object such as immutability (although not a requirement).

In most cases you shouldn't override the Equals method because developers that use your class will (should) never expect your Equals
method to check for value-equality unless it's explicitly documented to do so. For this reason, you should use an alternative means
to checking for value equality, such as the following (based on your Person example):

public bool EqualsNameAndPhone(Person person)
{
if (person == null)
throw new ArgumentNullException("person");

return person._Name == this._Name && person._Phone == this._Phone;
}

Personally, I'd rather just hard-code the comparison when consuming the class, but I acknowledge that your example might be
simplistic for the sake of brevity. Here's what I would do:

if (person1.Name == person2.Name && person1.Phone == person2.Phone)
// TODO: do something

Ask yourself the following questions to decided which is a better choice for you:

1. How often will I need to do this particular comparison?
not often: hard-code; often: encapsulate
2. Does the comparison require any operation that should be encapsulated by the class?
no: hard-code; yes: encapsulate
3. Will other developers (or even myself) know/bother to use my method instead of hard-coding?
mixed usage: hard-code; strict usage: encapsulate
4. Will coding this method save you any time?
no: hard-code; yes: encapsulate
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top