我正在尝试在列表之间创建一个支票,但我没有运气: - /
我有一个包含100个字段的游戏板,并使这个循环只将空字段添加到新列表中:
for(int i = 0; i < thisGame.boardFields.Count; i++)
{
if (thisGame.boardFields.Count != 0 && thisGame.boardFields [i] != null)
{
BoardField thisField = thisGame.boardFields [i];
if (thisField.owner == "0" && thisField.number != 13)
{
Tile tTile = new Tile();
tTile.color = thisField.color;
tTile.number = thisField.number.ToString();
tempBoard.Add (tTile);
}
}
}
然后我循环播放器5个牌,看看玩家是否有一个不可玩的牌,例如具有相同对象的空字段不可用,如下所示:
for (var i = 0; i < thisGame.playerTiles.Count; i++)
{
Tile tempTile = new Tile();
tempTile.color = thisGame.playerTiles[i].color;
tempTile.number = thisGame.playerTiles[i].number.ToString();
if (!tempBoard.Contains (tempTile))
{
testTile = tempTile;
print ("HUSTON WE HAVE A PROBLEM: " + tempTile.color + "-" + tempTile.number);
}
}
这是Tile类的定义:
public class Tile
{
public int id;
public string color;
public string number;
}
现在问题是,它会在播放器磁贴列表中的每5个磁贴上打印出来吗?玩家区块列表中的所有区块都可以在tempBoard
列表中找到?
我想念她的是什么?
希望得到帮助并提前致谢: - )
答案 0 :(得分:4)
工作Contains
需要检查两个对象之间的相等性。默认情况下,对于引用类型,它通过检查引用相等性来完成它。因此,在所有属性中具有相同类型且具有相同值的两个不同实例(内存中的对象)仍将导致它们不相等,并且Contains
返回false。
要克服这3个选项:
您需要让您的课程覆盖Equals
和GetHashCode
对象的方法。关于覆盖方法的参考文献:
另一个选择而不是覆盖类中的方法是创建一个实现IEquatable<Tile>
接口的类,然后使用重载:
list.Contains(searchedTile, new SomeClassImplementingInterface());
如果Equals
/ GetHashCode
的覆盖非常重要(不包括该类的所有属性)或者您无法控制{{1},则使用此标识} class。
使用linq&#39; Tile
方法:
Any
此外,使用object initializer syntax初始化对象很不错:
collection.Any(item => item.number == tempTile.number && item.color == temTile.color);
如果你有你的字段Tile tTile = new Tile
{
color = thisField.color,
number = thisField.number.ToString()
}
,他们应该被定义为属性:
public
关于属性与字段:
答案 1 :(得分:0)
根据此Stack Overflow回答(https://stackoverflow.com/a/9264597/1102726),如果您没有为IEquatable. Equals
提供替代,Contains
将进行参考比较。由于您刚刚实例化tempTile
,它会
永远不会在那个名单中。您可以在Tile
的定义中提供覆盖,也可以更改Contains(tempTile)
之类的tempBoard.Any(t => t.number == tempTile.number)
,或者将两个图块定义为相同。