2017-07-31 98 views
1

因此,我创建了一个Noughts和Crosses应用程序(我的美国朋友的Tic tac脚趾)只是为了练习一点而我偶然发现了一个问题。C#List.Contains在它应该返回true时

我在List<PlayerPositons>有3个项目,我试图寻找一个特定的位置。然而,当我使用LINQ方法Contains它不会返回真正的时候,我正在寻找一个我知道肯定的位置。

下面是代码:

private void CheckIfWinner(object sender, PlayerClickedOnBoardEventArgs e) { 
    if (e.CurrentPositions != null) { 
     var potentialWinnersPositions = e.CurrentPositions.GroupBy(r => r.Player).Where(r => r.Count() >= 3); 

     foreach (var item in potentialWinnersPositions) { 
      var verticalGrouping = item.Where(r => r.Player == item.Key).GroupBy(r => r.VerticalPosition); 
      //If there are three vertically then there must be a winner 
      foreach (var vert in verticalGrouping) { 
       if (vert.Select(r => r.VerticalPosition).Count() == 3) { 
        _view.WinnerMessage = $"Congratulations player {item.Key}. You won!"; 
        return; 
       } 
      } 

      var horizontalGrouping = item.Where(r => r.Player == item.Key).GroupBy(r => r.HorizontalPositon); 
      //If there are three hoirzontally then there must be a winner 
      foreach (var horiz in horizontalGrouping) { 
       if (horiz.Select(r => r.HorizontalPositon).Count() == 3) { 
        _view.WinnerMessage = $"Congratulations player {item.Key}. You won!"; 
        return; 
       } 
      } 

      //If item contains the center button then there is a possibility of a winner 
      //Happens here 
      if (item.Select(r => r).Contains(new Models.PlayerPosition(item.Key, Models.Position._verticalPosition.Middle, Models.Position._horizontalPosition.Middle))) { 
       if (item.Where(r => r.VerticalPosition == Models.Position._verticalPosition.Top) != null && item.Where(r => r.VerticalPosition == Models.Position._verticalPosition.Bottom) != null) { 
        _view.WinnerMessage = $"Congratulations player {item.Key}. You won!"; 
        return; 
       } 
      } 
     } 
    } 
} 

所以我试图寻找在广场和项目中心块包含下列项目:

PositionCollection positions = new PositionCollection() { 
    new PlayerPosition('x', Position._verticalPosition.Top, Position._horizontalPosition.Left), 
    new PlayerPosition('o', Position._verticalPosition.Middle, Position._horizontalPosition.Left), 
    new PlayerPosition('x', Position._verticalPosition.Middle, Position._horizontalPosition.Middle), 
    new PlayerPosition('o', Position._verticalPosition.Middle, Position._horizontalPosition.Right), 
    new PlayerPosition('x', Position._verticalPosition.Bottom, Position._horizontalPosition.Right), 
}; 

为什么Contains返回false?

编辑 - PlayerPosition类:

public class PlayerPosition : IEquatable<PlayerPosition>{ 
    public enum _verticalPosition { Top, Middle, Bottom }; 
    public enum _horizontalPosition { Left, Middle, Right }; 
    public PlayerPosition(char player, _verticalPosition vert, _horizontalPosition horiz) { 
     if (player != 'x' && player != 'o') { 
      throw new ArgumentException("Player must be either x or o."); 
     } 
     Player = player; 
     VerticalPosition = vert; 
     HorizontalPositon = horiz; 
    } 

    public char Player { get; set; } 
    public _verticalPosition VerticalPosition { get; set; } 
    public _horizontalPosition HorizontalPositon { get; set; } 

    public override bool Equals(object obj) { 
     PlayerPosition pos = (PlayerPosition)obj; 
     if (obj == null) { 
      return false; 
     } 
     else if (pos.HorizontalPositon == HorizontalPositon && pos.VerticalPosition == VerticalPosition 
       && pos.Player == Player) { 
      return true; 
     } 

     return false; 
    } 

    public override int GetHashCode() { 
     return base.GetHashCode(); 
    } 

    public bool Equals(PlayerPosition other) { 
     if (other == null) { 
      return false; 
     } 
     else if (other.HorizontalPositon == HorizontalPositon && other.VerticalPosition == VerticalPosition 
       && other.Player == Player) { 
      return true; 
     } 

     return false; 
    } 

    public static bool operator ==(PlayerPosition a, PlayerPosition b) { 
     return Equals(a, b); 
    } 

    public static bool operator !=(PlayerPosition a, PlayerPosition b) { 
     return !Equals(a, b); 
    } 
} 
+0

由于文档说所以*该方法通过使用默认的相等比较确定平等,由对象的实现为T(在列表中的值的类型)的IEquatable .Equals方法的限定。* –

+0

对,所以它不工作,因为它们都是参考类型? – Andrew

+1

顺便说一句,这看起来像可怕的代码,因为这是一个练习应用程序,尝试并简化它并解决它 –

回答

0

所以从我个人理解,LINQ Contains使用默认的对象Equals法计算的值是否相等。

在我的例子中,他们根据Equals算子不相等,所以我已经超越了EqualsGetHashCode方法。 Contains方法现在使用这些来计算它们是否相等。

呼吁Rufo爵士帮助我。

public class PlayerPosition { 
     public enum _verticalPosition { Top, Middle, Bottom }; 
     public enum _horizontalPosition { Left, Middle, Right }; 

     public PlayerPosition(char player, _verticalPosition vert, _horizontalPosition horiz) { 
      if (player != 'x' && player != 'o') { 
       throw new ArgumentException("Player must be either x or o."); 
      } 
      Player = player; 
      VerticalPosition = vert; 
      HorizontalPositon = horiz; 
     } 

     public char Player { get; set; } 
     public _verticalPosition VerticalPosition { get; set; } 
     public _horizontalPosition HorizontalPositon { get; set; } 

     public override bool Equals(object obj) { 
      PlayerPosition pos = (PlayerPosition)obj; 
      if (obj == null) { 
       return false; 
      } 
      else if (pos.HorizontalPositon == HorizontalPositon && pos.VerticalPosition == VerticalPosition 
        && pos.Player == Player) { 
       return true; 
      } 

      return false; 
     } 

     public override int GetHashCode() { 
      return Player.GetHashCode()^HorizontalPositon.GetHashCode()^VerticalPosition.GetHashCode(); 
     } 

     public static bool operator ==(PlayerPosition a, PlayerPosition b) { 
      return Equals(a, b); 
     } 

     public static bool operator !=(PlayerPosition a, PlayerPosition b) { 
      return !Equals(a, b); 

     } 
    } 
1

包含用于参考的比较检查.Equals()。也许你需要的是==检查实际坐标。 因此,而不是:

.Contains(new Models.PlayerPosition(item.Key, Models.Position._verticalPosition.Middle, Models.Position._horizontalPosition.Middle)) 

尝试类似:

.Any(r => r.VerticalPosition == Models.Position._verticalPosition.Middle && r.HorizontalPosition == Models.Position._horizontalPosition.Middle)) 
+1

你自己尝试了解决方案吗?你会得到相同的结果。默认比较比较引用和两个实例不具有相同的引用 –

+0

这也不工作,我已经覆盖了对象Equals方法,并得到它的工作,但它把另一个ForEach在那里,我不想要的。我会试图找出别的东西 – Andrew

相关问题