Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetHashCode good practice?

For a Delphi project (built with RAD Studio XE7), I want to create a dictionary of brushes. Each dictionary item contains a TMyBrush object as key, that describes the brush to retrieve, and a GDI+ brush as value.

The TMyBrush class contains 3 fields

  • An enumerated type to determine the kind of brush (solid, gradient, ...)
  • A TBrushInfo class that describes the brush content (color, wrap mode, ...)
  • A TRect that represents a clamp field

In my dictionary, I want to retrieve a brush based on his characteristics, and not on his instance. For example, I want to get a black solid brush from my dictionary by creating a local TMyBrush instance, configuring it to black solid, and getting the matching GDI+ value using the TryGetValue() function. For that, I created a TMyBrushComparer.

Writing the Equals() function isn't a problem for me. However I don't know what is the best practice to write the GetHashCode() function. I would tend to write a function like this:

function TMyBrushComparer.GetHashCode(const pValue: TMyBrush): Integer;
begin
    Result := BobJenkinsHash(pValue, SizeOf(TMyBrush), 0);
end;

however I feel that is not a very good practice, it is correct? So, what is the best practice to write a good GetHashCode() function for my TMyBrushComparer?

Regards

like image 846
Jean-Milost Reymond Avatar asked Dec 10 '16 13:12

Jean-Milost Reymond


People also ask

Should I override GetHashCode?

If you're implementing a reference type, you should consider overriding the Equals method if your type looks like a base type, such as Point, String, BigNumber, and so on. Override the GetHashCode method to allow a type to work correctly in a hash table.

What is the purpose of GetHashCode?

A hash code is a numeric value which is used to insert and identify an object in a hash-based collection. The GetHashCode method provides this hash code for algorithms that need quick checks of object equality.

How does GetHashCode work in C#?

GetHashCode method of the base class uses reflection to compute the hash code based on the values of the type's fields. In other words, value types whose fields have equal values have equal hash codes.

Is string GetHashCode deterministic?

The key point is that the hash codes are deterministic for a given program execution, that means the only time it'll be an issue is if you're saving the hash code outside of a process, and loading it into another one.


1 Answers

The code in the question hashes the address of the object rather than its value and so is not consistent with your definition of equality.

Your definition of equality is that three of the fields are equal. Your hash function should match that definition. Hash each of the three fields, and combine the values, for instance using the approach outlined here: https://stackoverflow.com/a/263416/505088

Two of your fields are value types. They are easy to hash to match value identity. The brush info field appears to be a reference type. So again you need to decide what form of identity you want (reference identity, value identity, or perhaps something else) and then implement matching equality test and hash.

like image 190
David Heffernan Avatar answered Sep 29 '22 09:09

David Heffernan