c# 包含对象不工作
c# contains object not working
我正在尝试在列表之间创建检查,但运气不好:-/
我有一个包含 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的定义class:
public class Tile
{
public int id;
public string color;
public string number;
}
现在我的问题是,它会打印在玩家板块列表中的每 5 个板块上吗? tempBoard
list?
我想念她什么?
希望得到帮助并提前致谢:-)
工作 Contains
需要检查两个对象之间的相等性。默认情况下,对于引用类型,它通过检查引用相等性来实现。因此,拥有两个相同类型且所有属性具有相同值的不同实例(内存中的对象)仍然会导致它们不相等,并且对于 Contains
到 return false.
要克服这 3 个选项:
您需要 class 来覆盖 Equals
和 GetHashCode
对象的方法。关于覆盖方法的参考:
- What is the best algorithm for an overridden System.Object.GetHashCode?
- Guidelines for Overriding Equals()
另一种选择,而不是重写 class 中的方法,是创建一个 class 实现 IEquatable<Tile>
接口,然后使用重载:
list.Contains(searchedTile, new SomeClassImplementingInterface());
如果 Equals
/GetHashCode
的覆盖非常重要(不包括 class 的所有属性)或者如果您没有控制权,我会使用它在 Tile
class.
使用linq的Any
方法:
collection.Any(item => item.number == tempTile.number && item.color == temTile.color);
另外,使用 object initializer syntax:
来初始化你的对象是很好的
Tile tTile = new Tile
{
color = thisField.color,
number = thisField.number.ToString()
}
如果您有自己的字段 public
,它们可能应该被定义为属性:
public class Tile
{
public int Id { get; set; }
public string Color { get; set; }
public string Number { get; set; }
}
关于属性与字段:
- What is the difference between a Field and a Property in C#?
- Public Fields versus Automatic Properties
根据这个 Stack Overflow 答案 (),如果您不为 IEquatable. Equals
提供覆盖,Contains
将进行参考比较。由于您刚刚实例化了 tempTile
,它将
永远不会在那个名单上。您可以在 Tile
的定义中提供该覆盖,或者将 Contains(tempTile)
更改为 tempBoard.Any(t => t.number == tempTile.number)
之类的内容,或者您将两个图块定义为相同。
我正在尝试在列表之间创建检查,但运气不好:-/
我有一个包含 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的定义class:
public class Tile
{
public int id;
public string color;
public string number;
}
现在我的问题是,它会打印在玩家板块列表中的每 5 个板块上吗? tempBoard
list?
我想念她什么?
希望得到帮助并提前致谢:-)
工作 Contains
需要检查两个对象之间的相等性。默认情况下,对于引用类型,它通过检查引用相等性来实现。因此,拥有两个相同类型且所有属性具有相同值的不同实例(内存中的对象)仍然会导致它们不相等,并且对于 Contains
到 return false.
要克服这 3 个选项:
您需要 class 来覆盖
Equals
和GetHashCode
对象的方法。关于覆盖方法的参考:- What is the best algorithm for an overridden System.Object.GetHashCode?
- Guidelines for Overriding Equals()
另一种选择,而不是重写 class 中的方法,是创建一个 class 实现
IEquatable<Tile>
接口,然后使用重载:list.Contains(searchedTile, new SomeClassImplementingInterface());
如果
Equals
/GetHashCode
的覆盖非常重要(不包括 class 的所有属性)或者如果您没有控制权,我会使用它在Tile
class.使用linq的
Any
方法:collection.Any(item => item.number == tempTile.number && item.color == temTile.color);
另外,使用 object initializer syntax:
来初始化你的对象是很好的Tile tTile = new Tile
{
color = thisField.color,
number = thisField.number.ToString()
}
如果您有自己的字段 public
,它们可能应该被定义为属性:
public class Tile
{
public int Id { get; set; }
public string Color { get; set; }
public string Number { get; set; }
}
关于属性与字段:
- What is the difference between a Field and a Property in C#?
- Public Fields versus Automatic Properties
根据这个 Stack Overflow 答案 (),如果您不为 IEquatable. Equals
提供覆盖,Contains
将进行参考比较。由于您刚刚实例化了 tempTile
,它将
永远不会在那个名单上。您可以在 Tile
的定义中提供该覆盖,或者将 Contains(tempTile)
更改为 tempBoard.Any(t => t.number == tempTile.number)
之类的内容,或者您将两个图块定义为相同。