2

这是我的结构...

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;
    }
}

我将这些用作字典的键,但我认为它们不能正确地相互等同。字典中的值是具有 bool 字段的对象。我有一个while循环对它们做一些事情并将bool更改为true,直到它们全部为true..它陷入无限循环,因为它们永远不会变为true..奇怪的是我没有超出范围错误或类似的东西,当我调试更改布尔值的位时,它似乎工作正常,但是当我在调试中查看字典时,所有布尔值仍然是错误的

(注意:我使用元组作为键,但我制作了这个结构,所以我可以轻松地相乘和相加)

我只是想和你确认一下...

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

那两次我访问字典时我访问的是同一个值对象?

编辑:这是字典中的值结构(我替换了上面的“东西”)

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

2 回答 2

2

这取决于是什么Thing。如果Thingstruct:否;该值在获取时被复制 - 尽管编译器通常会阻止您struct为即将被丢弃的 a 分配属性。如果是 a class,那么它应该是同一个对象实例;你的equals/hash-code看起来很合理。

于 2013-02-18T16:38:54.343 回答
1

您的语句_myDictionary[new Coord(4,5)].Connected = true;不应该编译,因为返回类型为结构(例如_myDictionary[new Coord(4,5)])的方法和属性返回这些结构类型的只读副本,而您正试图写入这样的只读结构。

为简洁起见,我将假装您的字典是Dictionary<int, RogueRoom>; 用户定义结构的事实Coordinate在这里并不重要。

如果您说var temp = _myDictionary[5];该语句将生成实例的可写副本RogueRoom。如果您说temp.Connected=true;这将修改该副本,但保留字典中的副本不变。如果您想更新存储在字典中的那个,您必须自己写回它:_myDictionary[5] = temp;.

如果您要更改RogueRoom为可变类,那么您可以说_myDictionary[5].Connected = true;修改Connected与 5 关联的对象的属性。然而,无论好坏,它也会修改Connected与存在于同一对象的任何其他引用关联的属性. 例如,如果要说_MyDictionary[2] = _MyDictionary[5];,则该语句_myDictionary[5].Connected = true;将设置与 2 关联的对象的 connected 属性(因为与 2 关联的对象与与 5 关联的对象是同一对象)。

有些人不喜欢可变结构,并建议您应该设计您的类型,以便代码必须这样说:

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

而不仅仅是更新的Connected属性temp并将其写回。我发现后一种风格不必要地丑陋和晦涩,但有些人更喜欢它。

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.

于 2013-04-03T17:13:59.040 回答