What is the best way to create your own GetHashCode method for a class in C#? Suppose I have a simple class (which overrides the Equals method), as follows:
class Test
{
public string[] names;
public double[] values;
public override bool Equals(object obj)
{
return (obj is Test) && this.Equals((Test)obj);
}
public bool Equals(Test t)
{
return names.Equals(t.names) && values.Equals(t.values);
}
}
Should I use the default code for the GetHashCode method?
public override int GetHashCode()
{
return base.GetHashCode();
}
Should I base the method on the contents of my class?
public override int GetHashCode()
{
return names.GetHashCode() + values.GetHashCode() ;
}
Or should I do something else?
The GetHashCode method provides this hash code for algorithms that need quick checks of object equality. For information about how hash codes are used in hash tables and for some additional hash code algorithms, see the Hash Function entry in Wikipedia. Two objects that are equal return hash codes that are equal.
It's my understanding that the original GetHashCode() returns the memory address of the object, so it's essential to override it if you wish to compare two different objects. EDITED: That was incorrect, the original GetHashCode() method cannot assure the equality of 2 values.
If you use eclipse, you can generate equals() and hashCode() using: Source -> Generate hashCode() and equals(). Using this function you can decide which fields you want to use for equality and hash code calculation, and Eclipse generates the corresponding methods.
GetHashCode returns a value based on the current instance that is suited for hashing algorithms and data structures such as a hash table. Two objects that are the same type and are equal must return the same hash code to ensure that instances of System.
System.Array
does not override GetHashCode
or Equals
, so they use reference equality. Therefore, you shouldn't call them.
To implement GetHashCode
, see this question.
To implement Equals
, use the SequenceEqual
extension method.
EDIT: On .Net 2.0, you'll have to write your own version of SequenceEqual
, like this:
public static bool SequenceEquals<T>(IList<T> first, IList<T> second) {
if (first == second) return true;
if (first == null || second == null) return false;
if (first.Count != second.Count) return false;
for (int i = 0; i < first.Count; i++)
if (!first[i].Equals(second[i]))
return false;
return true;
}
You could write it to take IEnumerable<T>
instead of IList<T>
, but it'd be somewhat slower because it wouldn't be able to exit early if the parameters have different sizes.
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