c#包含无效的对象

时间:2017-10-01 18:08:56

标签: c# list contains

我正在尝试在列表之间创建一个支票,但我没有运气: - /

我有一个包含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列表中找到?

我想念她的是什么?

希望得到帮助并提前致谢: - )

2 个答案:

答案 0 :(得分:4)

工作Contains需要检查两个对象之间的相等性。默认情况下,对于引用类型,它通过检查引用相等性来完成它。因此,在所有属性中具有相同类型且具有相同值的两个不同实例(内存中的对象)仍将导致它们不相等,并且Contains返回false。

要克服这3个选项:

  1. 您需要让您的课程覆盖EqualsGetHashCode 对象的方法。关于覆盖方法的参考文献:

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

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

    如果Equals / GetHashCode的覆盖非常重要(不包括该类的所有属性)或者您无法控制{{1},则使用此标识} class。

  3. 使用linq&#39; Tile方法:

    Any
  4. 此外,使用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

    关于属性与字段:

    最后看看naming conventions for C#

答案 1 :(得分:0)

根据此Stack Overflow回答(https://stackoverflow.com/a/9264597/1102726),如果您没有为IEquatable. Equals提供替代,Contains将进行参考比较。由于您刚刚实例化tempTile,它会 永远不会在那个名单中。您可以在Tile的定义中提供覆盖,也可以更改Contains(tempTile)之类的tempBoard.Any(t => t.number == tempTile.number),或者将两个图块定义为相同。