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 个选项:

  1. 您需要 class 来覆盖 EqualsGetHashCode 对象的方法。关于覆盖方法的参考:

  2. 另一种选择,而不是重写 class 中的方法,是创建一个 class 实现 IEquatable<Tile> 接口,然后使用重载:

    list.Contains(searchedTile, new SomeClassImplementingInterface());
    

    如果 Equals/GetHashCode 的覆盖非常重要(不包括 class 的所有属性)或者如果您没有控制权,我会使用它在 Tile class.

  3. 使用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

最后看看 naming conventions for C#

根据这个 Stack Overflow 答案 (),如果您不为 IEquatable. Equals 提供覆盖,Contains 将进行参考比较。由于您刚刚实例化了 tempTile,它将 永远不会在那个名单上。您可以在 Tile 的定义中提供该覆盖,或者将 Contains(tempTile) 更改为 tempBoard.Any(t => t.number == tempTile.number) 之类的内容,或者您​​将两个图块定义为相同。