包含引用类型的结构的 Hashset Equality 覆盖
Hashset Equality override for structs containing reference type
我正在尝试实现包含棋盘游戏状态的结构,因此我需要在 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
由于结构是值类型,当我创建新实例时:
Sokoban nextState = actualState;
其中 actualState 是以前初始化的实例,
它应该将 actualState
的所有字段复制到 nextState
。
所以 nextState
和 actualState
现在指向同一个 List>。 .
我的问题是,如何才能拥有该结构的正确副本?
如果我创建一个构造函数,如:
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;
}
有效。
但是,当我将这两个不同的实例添加到哈希集时,它们不会被识别为相同的。这是我覆盖 GetHashCode,Equals, ==, != operators 的代码:
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 天,谢谢 :)
查看代码,很有可能是这里的问题
public override int GetHashCode()
{
//(data).GetHashCode() !!! List<T>::GetHashCode()..
return (( sx+sy+bx+by+ cx+ cy).GetHashCode()+(data).GetHashCode());
}
data.GetHashCode()
对于结构的每个新实例都是唯一的,因此您得到的 GetHashCode()
可能会导致根据您的逻辑应该相等的实例的数量完全不同。更改您的 GetHashCode()
方法以满足您的需要。
我正在尝试实现包含棋盘游戏状态的结构,因此我需要在 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
由于结构是值类型,当我创建新实例时:
Sokoban nextState = actualState;
其中 actualState 是以前初始化的实例,
它应该将 actualState
的所有字段复制到 nextState
。
所以 nextState
和 actualState
现在指向同一个 List>。 .
我的问题是,如何才能拥有该结构的正确副本?
如果我创建一个构造函数,如:
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;
}
有效。 但是,当我将这两个不同的实例添加到哈希集时,它们不会被识别为相同的。这是我覆盖 GetHashCode,Equals, ==, != operators 的代码:
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 天,谢谢 :)
查看代码,很有可能是这里的问题
public override int GetHashCode()
{
//(data).GetHashCode() !!! List<T>::GetHashCode()..
return (( sx+sy+bx+by+ cx+ cy).GetHashCode()+(data).GetHashCode());
}
data.GetHashCode()
对于结构的每个新实例都是唯一的,因此您得到的 GetHashCode()
可能会导致根据您的逻辑应该相等的实例的数量完全不同。更改您的 GetHashCode()
方法以满足您的需要。