سؤال

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;
}
هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

Your statement _myDictionary[new Coord(4,5)].Connected = true; should not compile, since methods and properties whose return type is a struct (e.g. _myDictionary[new Coord(4,5)]) return read-only copies of those structure types and you are trying to write to such a read-only structure.

For brevity, I'm going to pretend your dictionary was a Dictionary<int, RogueRoom>; the fact that Coordinate is a user-defined structure doesn't matter here.

If you say var temp = _myDictionary[5]; that statement will generate a writable copy of the RogueRoom instance. If you say temp.Connected=true; that will modify that copy but leave the copy in the dictionary unchanged. If you wish to update the one stored in the dictionary, you would have to write it back yourself: _myDictionary[5] = temp;.

If you were to change RogueRoom to a mutable class, then you could say _myDictionary[5].Connected = true; to modify the Connected property of the object associated with 5. For better or for worse, however, it would also modify the Connected property associated with any other reference that exists to that same object. For example, if one were to say _MyDictionary[2] = _MyDictionary[5];, then the statement _myDictionary[5].Connected = true; would set the connected property of the object associated with 2 (since the object associated with 2 is the same object as is associated with 5).

Some people dislike mutable structures, and would suggest that you should design your type so that code would have to say something like:

var temp = _myDictionary[5];
_myDictionary[5] = new RogueRoom(temp.RoomField, true, temp.RealPos,
   temp.RogueRoomColors, temp.GridPos);

instead of just updating the Connected property of temp and writing it back. I find the latter style to be needlessly ugly and obscure, but some people prefer it.

As for the question of whether the thing should be a class, that depends upon whether you want each storage location of type RogueRoom to hold hold five independent pieces of information which are independent from those in any other storage location of that type, or whether you want to allow multiple storage locations of that type to refer to the same instance. There are definite usage cases for both scenarios; you need to determine which is right for you.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top