Search code examples
c#.netdictionarystructiequatable

Using struct as key for dictionary and weird stuff is happening


Heres my struct...

internal struct Coord : IEquatable<Coord>
{
    public int X { get; private set; }
    public int Y { get; private set; }

    public Coord(int x,int y) : this(){ X = x;
        Y = y;}

    //Overloaded operator functuions below
    //So I can easily multiply Coords by other Coords and ints and also add Coords together
    public static Coord operator *(Coord left, int right)
    {
        return new Coord(left.X * right, left.Y * right);
    }

    public static Coord operator *(Coord left, Coord right)
    {
        return new Coord(left.X * right.X, left.Y * right.Y);
    }

    public static Coord operator +(Coord left, Coord right)
    {
        return new Coord(left.X + right.X, left.Y + right.Y);
    }

    public static Coord operator -(Coord left, Coord right)
    {
        return new Coord(left.X - right.X, left.Y - right.Y);
    }


    public override int GetHashCode()
    {
        int hash = 17;
        hash = hash * 31 + X;
        hash = hash * 31 + Y;
        return hash;
    }

    public override bool Equals(object other)
    {
        return other is Coord ? Equals((Coord)other) : false;
    }

    public bool Equals(Coord other)
    {
        return X == other.X &&
               Y == other.Y;
    }
}

I'm using these as keys for a dictionary, but I dont think they are equating to each other properly.. The values in the dictionary are objects with a bool field. I have a while loop that does stuff to them and changes the bool to true until they are all true.. It gets stuck in an infinite loop as they never get changed to true.. Whats weird is that I dont get any out of range errors or anything like that and when I debug the bit where the bool is changed it seems to work fine but when I look at the dictionary in debug all the bools are still false

(note: i was using a Tuple as the key but I made this struct so I could multiply and add them easily )

I just want to check with you that...

  _myDictionary = new Dictionary<Coord, RogueRoom>();
  _myDictionary[new Coord(4,5)] = new RogueRoom();
  _myDictionary[new Coord(4,5)].Connected = true

Those two times I access the dictionary I am accessing the same value object?

EDIT: Here is the value struct in the dictionary (I replaced "thing" above)

internal struct RogueRoom
{
    public Room RoomField;
    public bool Connected;
    public Rectangle Realpos;
    public Color[] RogueRoomColors;
    public Coord Gridpos;
}

Solution

  • It depends on what Thing is. If Thing is a struct: no; the value is copied when it is fetched - although the compiler will usually stop you assigning properties against a struct that is about to be thrown away. If it is a class, then it should be the same object instance; your equals/hash-code look reasonable.