2017-07-31 100 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

相關問題