C# 如何在列表中搜索特定元素的不同实例?
我有一个名为Point的类元素列表,我想用另一系列Point从列表中删除,我使用以下代码:C# 如何在列表中搜索特定元素的不同实例?,c#,C#,我有一个名为Point的类元素列表,我想用另一系列Point从列表中删除,我使用以下代码: po = new Point(x,y); if (l.Contains(po)) l.Remove(po); 发生的情况是,条件永远不会满足(我想这是因为列表中显然不包含新的点,而是在别处生成的另一个实例) contains是否有一种方法可以检查元素是否相同,即使不是实际的相同实例?尝试: if (l.Any(a => a.x == po.x && a.y == po.y)) 要
po = new Point(x,y);
if (l.Contains(po))
l.Remove(po);
发生的情况是,条件永远不会满足(我想这是因为列表中显然不包含新的点,而是在别处生成的另一个实例)
contains是否有一种方法可以检查元素是否相同,即使不是实际的相同实例?尝试:
if (l.Any(a => a.x == po.x && a.y == po.y))
要解决整个问题,请尝试以下方法:
l = l.Where(a => a.x != po.x || a.y != po.y);
这将为您提供没有重复项的剩余项。您必须重写
Equals
以使包含的内容按预期工作,或者使用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;
}
}
}
现在,您可以在引擎盖下使用哪个使用等于
。您不需要检查列表是否包含以下对象:
bool contained = l.Remove(po);
您必须定义如何比较两个点
类实例,即是什么使它们相等
在你的例子中,当x和y值都相同时,你希望它们相等,对吗
让您的点
类继承IEqualityComparer
接口。实现此接口:
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;
}
}
类点:IEqualityComparer
{
私人互联网;
公共整数x
{
获取{return\ux;}
设置{ux=value;}
}
私人国际;
公共智力
{
获取{return\u y;}
设置{u y=value;}
}
公共布尔等于(点p1,点p2)
{
//如果两个点的x和y值相同,则返回true
//否则返回false。
如果(p1==null | | p2==null)
返回false;
返回值(p1.x==p2.x)和&(p1.y==p2.y);
}
公共int GetHashCode(点obj)
{
返回对象x^obj.y;
}
}
请显示点的定义;这可能是一个引用相等与值相等的问题。假设您使用的是列表
,则上的msdn文档会准确地告诉您它是如何工作的。很明显,它给出了一些条件为真,我无法真正检查整个程序的原因。删除不起作用,我也可以从任何一个获取索引吗?@user3161621您可以使用linq方法的IndexOf(检查-1)和List.RemoveAtI添加到我的答案中。听起来你实际上不想删除任何东西,但是简单的过滤器很好,这很好,也更容易,因为当我有更复杂的东西时,我可以简单地调整相等值使其工作,ty@user3161621:不客气,记住接受回答;)