Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make a hashcode for a custom data structure?

Tags:

c#

hash

I've made a custom "Coordinate" data structure which defines the position of an object according to a certain system.

A coordinate is defined as follows:

public class Coordinate
{
    public int X;
    public int Y;
    private int face;
    public int Face
    {
        get { return face; }
        set
        {
            if (value >= 6 | value < 0)
                throw new Exception("Invalid face number");
            else
                face = value;
        }
    }
    private int shell;
    public int Shell
    {
        get { return shell; }
        set
        {
            if (value < 0)
                throw new Exception("No negative shell value allowed");
            else
                shell = value;
        }
    }

    public Coordinate(int face, int x, int y, int shell)
    {
        this.X = x;
        this.Y = y;
        this.face = face;
        this.shell = shell;
    }

    public static Coordinate operator +(Coordinate a, Coordinate b)
    {
        return new Coordinate(a.Face + b.Face, a.X + b.X, a.Y + b.Y, a.Shell + b.Shell);
    }

    public override bool Equals(object obj)
    {
        Coordinate other = (obj as Coordinate);
        if (other == null)
            return false;
        else
            return (Face == other.Face && Shell == other.Shell && X == other.X && Y == other.Y);
    }
}

Or, to summarize, it contains an int Face (0 to 5), an int X, int Y, and int Shell. X, Y, and Shell are all bound below at 0 (inclusive).

I have no experience at all in hash codes. I need to compare them to see if they are equal. I tried this:

private const int MULTIPLIER = 89;

[...]

int hashCode = 1;
hashCode = MULTIPLIER * hashCode + obj.X.GetHashCode();
hashCode = MULTIPLIER * hashCode + obj.Y.GetHashCode();
hashCode = MULTIPLIER * hashCode + obj.Face.GetHashCode();
hashCode = MULTIPLIER * hashCode + obj.Shell.GetHashCode();
return hashCode;

Going off something I found while Googling. But when I try to compile the code with this method, I'm pretty sure it runs into collisions, as it never finishes building. Probably getting into all sorts of messy loops thinking a bunch of the coordinates are the same or somesuch.

I'm sorry this question is rather elementary, but for some reason I'm stumped. I'm just looking for advice on how to write this hash code so that it doesn't collide.

like image 547
A-Type Avatar asked Oct 28 '11 03:10

A-Type


1 Answers

If well this is not the best way, it can be a good enough approach:

public override int GetHashCode()
{
   return string.Format("{0}-{1}-{2}-{3}", X, Y, Face, Shell).GetHashCode();
}

Update: Take a look at this article: http://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/

like image 169
lontivero Avatar answered Dec 29 '22 20:12

lontivero