C#List.Contains确实应该返回true

时间:2017-07-31 23:36:26

标签: c# linq

所以我正在为我的美国朋友制作一个小Noughts and Crosses应用程序(Tic tac toe),只是为了练习一点,我偶然发现了一个问题。

我在List<PlayerPositons>中有3个项目,我试图寻找某个位置。但是当我使用LINQ方法Contains时,在查找我确定知道的位置时,它不会返回true。

以下是代码:

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);
    }
}

2 个答案:

答案 0 :(得分: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)

根据我的理解,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);

        }
    }