Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用struct作为字典的键和奇怪的事情正在发生_C#_.net_Dictionary_Struct_Iequatable - Fatal编程技术网

C# 使用struct作为字典的键和奇怪的事情正在发生

C# 使用struct作为字典的键和奇怪的事情正在发生,c#,.net,dictionary,struct,iequatable,C#,.net,Dictionary,Struct,Iequatable,这是我的结构 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 //S

这是我的结构

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

这取决于什么是
东西。如果
事物
结构
:否;获取值时会复制该值-尽管编译器通常会停止您对即将丢弃的
结构指定属性。如果它是一个
,那么它应该是同一个对象实例;你的等号/散列码看起来很合理。

你的陈述
\u myDictionary[new Coord(4,5)]。Connected=true
不应编译,因为返回类型为结构(例如,
\u myDictionary[new Coord(4,5)]
)的方法和属性返回这些结构类型的只读副本,并且您正试图写入这种只读结构

为简洁起见,我将假设您的词典是一本
词典
Coordinate
是用户定义的结构这一事实在这里并不重要

如果你说
var temp=_myDictionary[5]
该语句将生成
eRoom
实例的可写副本。如果你说
temp.Connected=true将修改该副本,但保留字典中的副本不变。如果您希望更新字典中存储的内容,您必须自己写回:
\u myDictionary[5]=temp

如果要将
更改为可变类,则可以说
\u myDictionary[5]。Connected=true
修改与5关联的对象的
Connected
属性。但是,不管是好是坏,它还将修改与存在于同一对象的任何其他引用关联的
Connected
属性。例如,如果一个人说
\u MyDictionary[2]=\u MyDictionary[5]
,然后是语句
\u myDictionary[5]。Connected=true将设置与2关联的对象的已连接属性(因为与2关联的对象与与与5关联的对象相同)

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

var temp = _myDictionary[5];
_myDictionary[5] = new RogueRoom(temp.RoomField, true, temp.RealPos,
   temp.RogueRoomColors, temp.GridPos);
而不仅仅是更新
temp
Connected
属性并将其写回。我发现后一种风格不必要地丑陋和晦涩,但有些人更喜欢它


至于这个东西是否应该是一个类的问题,这取决于您是否希望
类型的每个存储位置都保存五条独立的信息,这些信息独立于该类型的任何其他存储位置中的信息,或者是否允许该类型的多个存储位置引用同一实例。两种场景都有明确的用例;您需要确定哪一个适合您。

请给出一个简短但完整的示例,说明它不能正确等同。我觉得Struct很好。错误一定在别处?您是否使用==在任何地方比较它们?因为没有重载运算符==()是结构还是类@GuyeIncognito则此代码不会编译。您应该得到错误:“无法修改[…]的返回值,因为它不是变量”。字典索引器正在返回
Thing
值的副本,因此您正在修改该副本。这是一个常见的错误,实际上总是一个错误,所以它实际上是一个编译器错误。
internal struct RogueRoom
{
    public Room RoomField;
    public bool Connected;
    public Rectangle Realpos;
    public Color[] RogueRoomColors;
    public Coord Gridpos;
}
var temp = _myDictionary[5];
_myDictionary[5] = new RogueRoom(temp.RoomField, true, temp.RealPos,
   temp.RogueRoomColors, temp.GridPos);