什么是Collection.Contains()用来检查现有的对象?
我有一个强types的自定义对象列表MyObject,它具有属性Id以及其他一些属性。
假设MyObject的Id将其定义为唯一的,并且我想要检查我的集合是否已经有一个Id为1的MyObject对象,然后再将我的新MyObject添加到集合中。
我想要使用if(!List.Contains(myObj)),但是我该如何强制MyObject的只有一个或两个属性将其定义为唯一的事实?
我可以使用IComparable? 或者我只需要重写一个Equals方法,但是我需要先inheritance一些东西吧?
谢谢
List<T>.Contains
使用EqualityComparer<T>.Default
,如果types实现它,则使用IEquatable<T>
,否则使用IEquatable<T>
。
你可以实现IEquatable<T>
但如果你这样做,重写IEquatable<T>
是一个好主意,如果你这样做,重写GetHashCode()
是一个很好的主意:
public class SomeIDdClass : IEquatable<SomeIDdClass> { private readonly int _id; public SomeIDdClass(int id) { _id = id; } public int Id { get { return _id; } } public bool Equals(SomeIDdClass other) { return null != other && _id == other._id; } public override bool Equals(object obj) { return Equals(obj as SomeIDdClass); } public override int GetHashCode() { return _id; } }
请注意,哈希码涉及到相等的标准。 这是至关重要的。
这也使得它适用于任何其他情况下,如由具有相同的ID定义的相等是有用的。 如果你有一个需要检查一个列表是否有这样的对象,那么我可能会build议只是在做:
return someList.Any(item => item.Id == cmpItem.Id);
List<T>
使用由EqualityComparer<T>.Default
返回的比较器,并根据以下文档 :
Default属性检查typesT是否实现了System.IEquatable(Of T)接口,如果是,则返回一个使用该实现的EqualityComparer(Of T)。 否则,它返回一个EqualityComparer(Of T),它使用由T提供的Object.Equals和Object.GetHashCode的重写。
所以你可以在你的自定义类上实现IEquatable<T>
,或者重写Equals
(和GetHashCode
)方法来根据你需要的属性进行比较。 或者你可以使用linq:
bool contains = list.Any(i => i.Id == obj.Id);
你可以使用LINQ来做到这一点很容易。
var result = MyCollection.Any(p=>p.myId == Id); if(result) { //something }
您可以覆盖Equals和GetHashCode,实现一个IEqualityComparer<MyObject>
并在Contains
调用中使用它,或者使用Any
if (!myList.Any(obj => obj.Property == obj2.Property && obj.Property2 == obj2.Property2)) myList.Add(obj2);
您可以使用IEquatable<T>
。 在你的类中实现这个,然后检查传递给Equals的T是否具有相同的Id.Id. 我敢肯定这是检查字典中的一个键,但我没有用它来收集。
首先用IEqualityComparer定义助手类。
public class MyEqualityComparer<T> : IEqualityComparer<T> { Func<T, int> _hashDelegate; public MyEqualityComparer(Func<T, int> hashDelegate) { _hashDelegate = hashDelegate; } public bool Equals(T x, T y) { return _hashDelegate(x) == _hashDelegate(y); } public int GetHashCode(T obj) { return _hashDelegate(obj); } }
然后在您的代码中,只需定义比较器并使用它:
var myComparer = new MyEqualityComparer<MyObject>(delegate(MyObject obj){ return obj.ID; }); var result = collection .Where(f => anotherCollection.Contains(f.First, myComparer)) .ToArray();
这样你可以定义如何计算平等而不修改你的类。 您也可以使用它来处理来自第三方库的对象,因为您无法修改其代码。