|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Overriding Equals methodI 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(); } } 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. Neven Klofutar wrote: Show quote > 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(); > } > } 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 -- Show quoteDave Sexton "Neven Klofutar" <neven.klofutar@**re...m.o..v...e**vip.hr> wrote in message news:eswY4n18GHA.4348@TK2MSFTNGP03.phx.gbl... > 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(); > } > } > |
|||||||||||||||||||||||