我有一个结构IntVector2,它有一个X和Y属性。 +运算符被
覆盖public static IntVector2 operator +(IntVector2 value1, IntVector2 value2)
{
value1.X += value2.X;
value1.Y += value2.Y;
return value1;
}
在带有contains方法的List中使用它时,它不会检查加法的总值,而只检查变量" current"
if (visited.Contains(current + dir))
continue;
这里到底发生了什么?
编辑:这里是变量值的屏幕截图,以及一个等于我期望包含值检查的变量声明。
https://dl.dropboxusercontent.com/u/30062610/Brokestuff.png
Edit2:这里是该方法的完整代码,它是A * Pathfinding算法从起始向量中找到结束向量的开始。
public Path Pathfind(IntVector2 start, IntVector2 end)
{
Queue<IntVector2> fillQueue = new Queue<IntVector2>();
List<IntVector2> visited = new List<IntVector2>();
fillQueue.Enqueue(start);
IntVector2 current;
while (fillQueue.Count > 0)
{
current = fillQueue.Dequeue();
foreach (IntVector2 dir in Directions)
{
if (GetCell(current + dir).IsWall)
continue;
else
{
IntVector2 newstuff = current + dir;
if (visited.Contains(current + dir))
continue;
if ((current + dir) == end)
{
//We've reached the target, traceback the path and return it.
}
visited.Add(current);
fillQueue.Enqueue(current + dir);
}
}
}
return null;
}
编辑3:即使使用与开头具有不同值的newstuff变量,也会触及continue。我不确定它可以做什么。我的等于覆盖仅检查X和Y是否相等,如果是则返回true。
这里是整个IntVector2代码:http://pastebin.com/ic108SeF
编辑4:我将+运算符修改为:
public static IntVector2 operator +(IntVector2 value1, IntVector2 value2)
{
return new IntVector2((value1.X + value2.X), (value1.Y + value2.Y));
}
问题仍然存在。
答案 0 :(得分:1)
Equals
方法中有一个拼写错误:
public override bool Equals(object obj)
{
if (obj is IntVector2)
{
return Equals((IntVector2)this); // <-- "this" should be "obj"
}
}
错误的代码会将this
与this
进行比较,因此它始终返回true
。
答案 1 :(得分:1)
好的,我相信我找出了你的问题。
您的等于覆盖不是覆盖,您可以在代码中将其作为:
public bool Equals(IntVector2 other) {
return (X == other.X) && (Y == other.Y);
}
你在那里做了什么,增加了一个名为Equals的方法。因此,您实际上已经重载了需要覆盖的实际等于方法。 Contains不会调用你的equals方法,因为它会调用带有对象的原始方法。
当你覆盖正确的equals方法时,你应该在实践中实现GetHashCode并使用GetHashCode来确定对象是否真正相等。
在你的情况下你不会有一个问题没有覆盖GetHashCode,因为你在IntVector2的另一个副本中基于两个整数相同的平均值,并且你不能真正计算它的整数哈希码作为X和Y都是整数。如果你在这里做了一个GetHashCode实现,你可能会在以后遇到bug,如果你有大量的bug,你最终可能会得到不相等的对象的dupe哈希码。
以下是您应该尝试的更新代码。
public struct IntVector2
{
public int X { get; set; }
public int Y { get; set; }
public static IntVector2 operator +(IntVector2 value1, IntVector2 value2)
{
value1.X += value2.X;
value1.Y += value2.Y;
return value1;
}
public override int GetHashCode()
{
//overrode this to get rid of warning
return base.GetHashCode();
}
//This equals get's called, notice the override keyword
public override bool Equals(object obj)
{
if (obj is IntVector2)
{
IntVector2 vObj = (IntVector2)obj;
return vObj.X == this.X && vObj.Y == this.Y;
}
return false;
}
//This won't get called, it's not part of the framework, this is adding a new overload for equals that .Net won't know about.
public bool Equals(IntVector2 other)
{
return (X == other.X) && (Y == other.Y);
}
public override string ToString()
{
return string.Format("{ value1: {0}, value2: {0} }", X, Y);
}
}
答案 2 :(得分:-1)
使用当前代码,Contains无法确定两个结构实例的相等性。如果重写IntVector2 :: GetHashCode,以便相同的值返回相同的哈希值,它应该按预期开始工作。