如何在列表中搜索特定元素的不同实例?

时间:2014-05-15 11:20:29

标签: c#

所以我有一个名为Point的类的元素列表l,我想用另一个Point系列从这个列表中删除,我使用这段代码:

po = new Point(x,y);
if (l.Contains(po))
l.Remove(po);

发生的情况是条件永远不会满足(我想因为列表显然不包含新的Point而是另一个在其他地方生成的实例) 即使不是实际相同的实例,也没有一种方法可以检测元素是否相同?

3 个答案:

答案 0 :(得分:1)

尝试:

if (l.Any(a => a.x == po.x && a.y == po.y))

要解决完整问题,请尝试以下方法:

l = l.Where(a => a.x != po.x || a.y != po.y);

这应该会给你剩下的没有重复的项目。

答案 1 :(得分:1)

您必须覆盖Equals才能使Contains按预期工作或使用LINQ:

l = l.Where(p => p.X != po.X || p.Y != po.Y).ToList();

如果x和y相等,假设两个点相等。

以下是一个覆盖Equals + GethashCode的类的示例:

public class Point
{
    public int X { get; set; }
    public int Y { get; set; }

    public override bool Equals(object obj)
    {
        Point p2 = obj as Point;
        if (p2 == null) return false;
        return X == p2.X && Y == p2.Y;
    }

    public override int GetHashCode()
    {
        unchecked
        {
            int hash = 17;
            hash = hash * 23 + X;
            hash = hash * 23 + Y;
            return hash;
        }
    }
}

现在,您可以使用List.Remove来使用Equals。您无需检查列表是否包含对象:

bool contained = l.Remove(po);

答案 2 :(得分:0)

你必须定义如何比较两个Point类实例,即是什么使它们相等?

在你的情况下,当x和y值相同时,你希望它们相等,对吗?

带你Point课,让它继承IEqualityComparer<Point>界面。实现此接口:

class Point : IEqualityComparer<Point>
{
    private int _x;
    public int x
    {
        get { return _x; }
        set { _x = value; }
    }

    private int _y;
    public int y
    {
        get { return _y; }
        set { _y = value; }
    }

    public bool Equals(Point p1, Point p2)
    {
        // Returns true if both points have the same x and y values
        // Returns false otherwise.
        if (p1 == null || p2 == null)
           return false;

        return (p1.x == p2.x) && (p1.y == p2.y);
    }

    public int GetHashCode(Point obj)
    {
        return obj.x ^ obj.y;
    }
}