Hashset Equality覆盖包含引用类型的结构

时间:2015-04-06 15:34:44

标签: c# struct copy hashset

我正在尝试实现包含棋盘游戏状态的struct,所以我需要HashSet中游戏的多个状态。

数据部分如下所示:

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

当struct是值类型时,当我使用:

创建新实例时
Sokoban nextState = actualState; 

其中actualState是以前初始化的实例, 它应该将actualState的所有字段复制到nextState。 因此,nextStateactualState现在指向相同的列表&gt;。 。 我的问题是,怎样才能拥有这个结构的正确副本? 如果我创建一个像:

这样的构造函数
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;
     }

它有效。 但是,当我将这两个不同的实例添加到hashset时,它们不会被识别为相同。这是我的覆盖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;       
    }      

我不知道我在哪里犯错,如果您有任何意见或评论,我很乐意接受任何帮助,我已经坚持了3天,谢谢:)

1 个答案:

答案 0 :(得分:0)

查看代码,问题很可能就在这里

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

data.GetHashCode()对于结构的每个新实例都是唯一的,因此结果GetHashCode()可能会导致根据您的逻辑应该相等的实例的数量完全不同。更改您的GetHashCode()方法以满足您的需求。