简体   繁体   English

对包含引用类型的结构的哈希集相等替代

[英]Hashset Equality override for structs containing reference type

I am trying to implement struct containing state of a board game, so I need multiple states of a game in a HashSet. 我正在尝试实现包含棋盘游戏状态的结构,因此我需要在HashSet中实现游戏的多个状态。

Data part looks like this: 数据部分如下所示:

struct Sokoban
{

    public List<List<char>> data;   // data matrix
    public int sx, sy;              // sokoban's position
    public int bx, by;              // box position
    public int cx, cy;              // final box position

As struct are value types, when I create new instance with: 作为结构是值类型,当我使用以下方法创建新实例时:

Sokoban nextState = actualState; 

where actualState is a formerly initialized instance, it should copy all fields of actualState to nextState . 如果ActualState是以前初始化的实例,则应将actualState所有字段复制到nextState So nextState and actualState now points to the same List>. 因此, nextStateactualState现在指向相同的List>。 . My question is, how can have a proper copy of this struct? 我的问题是,如何获得该结构的正确副本? If I create a constructor like: 如果我创建一个类似的构造函数:

public Sokoban(Sokoban originalSokoban)          
    {

        this.sx = originalSokoban.sx;
        this.sy = originalSokoban.sy;
        this.bx = originalSokoban.bx;
        this.by = originalSokoban.by;
        this.cx = originalSokoban.cx;
        this.cy = originalSokoban.cy;


        List<List<char>> data2 = new List<List<char>>();

        for (int i = 0; i < originalSokoban.data.Count(); i++)
        {

            data2.Add( new List<char>(originalSokoban.data[i]));
        }
        this.data = data2;
     }

it works. 有用。 But, when I add these two distinct instances to hashset they are not recognized as same. 但是,当我将这两个不同的实例添加到哈希集时,它们不会被识别为相同的实例。 This is my code for overriden GetHashCode,Equals, ==, != operators : 这是我的代码,用于重写GetHashCode,Equals,==,!=运算符:

    public override int GetHashCode()
    {
        return (( sx+sy+bx+by+ cx+ cy).GetHashCode()+(data).GetHashCode());
    }          

    public static bool operator ==(Sokoban x, Sokoban y)
    {
        bool isEqual = true;
        for (int i = 0; i < x.data.Count(); i++)
        {
            for (int j = 0; j < x.data[0].Count(); j++)
            {
                if (x.data[i][j] != y.data[i][j])
                {
                    isEqual = false;
                }
            }
        }

        return isEqual &&
        x.sx == y.sx &&
        x.sy == y.sy &&
        x.bx == y.bx &&
        x.by == y.by &&
        x.cx == y.cx &&
        x.cy == y.cy;
    }

    public static bool operator !=(Sokoban x, Sokoban y)
    {
        return !(x == y);
    }

    public override bool Equals(object obj)
    {
         return obj is Sokoban && this == (Sokoban)obj;       
    }      

I don't know where I'm making mistake, if you have any comments or remarks I'll gladly accept any help, I'm stuck with this for 3 days, thank you :) 我不知道我在哪里犯错,如果您有任何意见或建议,我将很乐意接受任何帮助,我们坚持了3天,谢谢您:)

Looking on the code, most likely the problem is here 查看代码,很可能是这里的问题

 public override int GetHashCode()
 {
   //(data).GetHashCode() !!! List<T>::GetHashCode()..
   return (( sx+sy+bx+by+ cx+ cy).GetHashCode()+(data).GetHashCode());
 }    

data.GetHashCode() is unique for every new instance of the struct, so your resulting GetHashCode() may result in totally different number for instances that are supposed to be equal according to your logic. data.GetHashCode()对于该结构的每个新实例都是唯一的,因此根据逻辑,您得出的GetHashCode()可能导致data.GetHashCode()实例数。 Change your GetHashCode() method to meet your needs. 更改您的GetHashCode()方法以满足您的需求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM