昨天我在C#代码中发现了一个奇怪的行为。 我的设置是(不完全,但可以比较)以下内容:
用户看到一个网格的复选框,其中我在coords 0,0的中间指定了复选框。
我写了一个结构,以便更容易地比较两个坐标:
public struct Coord
{
public int x, y;
public static bool operator == (Coord coord1, Coord coord2)
{
return coord1.x == coord2.x && coord1.y == coord2.y;
}
public static bool operator != (Coord coord1, Coord coord2)
{
return coord1.x != coord2.x || coord1.y != coord2.y;
}
public override int GetHashCode()
{
return this.x.GetHashCode() ^ this.y.GetHashCode();
}
public override bool Equals(object obj)
{
if (!(obj is Coord))
return false;
Coord coord = (Coord)obj;
if (coord.x == this.x && coord.y == this.y)
return true;
return false;
}
}
对于一个复选框,我使用一个名为Position的类,它继承自标准的WinForms复选框:
public class Position : CheckBox
{
public Coord coord;
public List<Position> nearPositions = new List<Position>();
public Position(int x, int y)
{
this.coord.x = x;
this.coord.y = y;
}
protected override void OnClick(EventArgs e)
{
if (this.Checked)
return;
base.OnClick(e);
this.checkConnections();
}
private void checkConnections()
{
foreach (Position position in this.nearPositions)
{
Route route = new Route(this, position);
}
}
}
如您所见,用户只能点击每个复选框一次 列表nearPositions仅包含此附近的点击复选框 现在在checkConnections()方法中我试图找出所有(或仅一些)点击的复选框可以连接到一个圆圈。 因此,我为每个可能的路径创建了我的类Route的新对象。
public class Route
{
private Position startPosition;
private List<Position> nodes = new List<Position>();
public Route(Position startPosition, Position nextPosition)
{
this.startPosition = startPosition;
this.nodes.Add(nextPosition);
this.findConnection();
}
public Route(Route route, Position nextPosition)
{
this.startPosition = route.startPosition;
this.nodes = route.nodes;
this.Add(nextPosition);
this.findConnection();
}
private void findConnection()
{
if (this.nodes.Count > 2 && this.nodes[this.nodes.Count - 1].nearPositions.Contains(this.startPosition))
{
//HERE THE ROUTE IS A CIRCLE
return;
}
List<Position> nextPositions = this.nodes[this.nodes.Count - 1].nearPositions.FindAll(p => !p.Equals(this.startPosition) && !this.nodes.Contains(p));
foreach (Position position in nextPositions)
{
if (this.nodes[this.nodes.Count - 1].nearPositions.FindAll(p => !p.Equals(this.startPosition) && !this.nodes.Contains(p)).Contains(position)) //TODO strange problem here...bad workaround need to fix
{
Route route = new Route(this, position);
}
}
}
}
请记住,我为每个可能性创建了一个Route对象。因此,如果圆圈包含许多复选框,则同时存在许多Route对象。也许重现我的问题很重要 Route始终具有相同的startPosition。它是用户点击的位置 在List节点中,我保存了构建cricle的步骤。
现在我得到的是findConnection()方法内部的List nextPosition有时包含在this.nodes [this.nodes.Count - 1] .nearPositions列表中甚至不存在的位置。这就是我在foreach循环中添加额外条件的原因。
我的想法,它可能是.FindAll()方法的一个错误,或同时出现多个eoutes的问题。
所以我的问题:
你能重现一下我的问题吗?
它来自哪里?
3.我该如何解决?
感谢您的回复!
答案 0 :(得分:1)
您应该尝试查明问题并发布更短的代码,以显示不适合您的内容。阅读所有细节并找出算法有点费时,大部分细节都不相关。
那就是说,你所看到的一件可疑的事情就是你定义Coord
结构的方式。你赋予它一个相等的运算符覆盖,它正确地比较了成员,但在你的Equals
覆盖中你不比较成员。
如果您的问题是FindAll
无法正常运行,并且您使用调试器验证了列表内容是否正确,则此Equal
覆盖可能是问题的原因。< / p>
您还应该更改GetHashCode
覆盖以合并成员的值。
答案 1 :(得分:0)
我找到了解决方案 问题出在
中public Route(Route route, Position nextPosition)
{
this.startPosition = route.startPosition;
this.nodes = route.nodes;
this.Add(nextPosition);
this.findConnection();
}
新路由仅获取对前一路由节点的引用,但它应具有自己的节点列表 所以我把它改成了
public Route(Route route, Position nextPosition)
{
this.startPosition = route.startPosition;
this.nodes.AddRange(route.nodes);
this.Add(nextPosition);
this.findConnection();
}
我应该早点看到。对不起!