Collection.Contains()用于检查现有对象的内容是什么?

时间:2010-09-03 17:11:10

标签: c# collections contains

我有一个强类型的自定义对象列表MyObject,它有一个属性Id和一些其他属性 假设MyObject的Id将其定义为唯一,我想在将新的MyObject添加到集合之前检查我的集合是否还没有Id为1的MyObject对象。
我想使用if(!List.Contains(myObj))但是如何强制只有MyObject的一个或两个属性将其定义为唯一的这一事实?
我可以用IComparable吗?或者我只需要覆盖一个Equals方法,但我需要首先继承一些东西吗?



由于

6 个答案:

答案 0 :(得分:46)

List<T>.Contains使用EqualityComparer<T>.Default,如果类型实现IEquatable<T>,则使用object.Equals,否则使用IEquatable<T>

您可以实施object.Equals,但如果您这样做,则覆盖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; } } 那样做:

return someList.Any(item => item.Id == cmpItem.Id);

请注意,哈希码与相等标准相关。这很重要。

这也使它适用于由具有相同ID定义的相等有用的任何其他情况。如果您有一个要求来检查列表是否有这样的对象,那么我可能会建议您这样做:

{{1}}

答案 1 :(得分:28)

List<T>使用EqualityComparer<T>.Default返回的比较器,并根据documentation

  

Default属性检查是否   type T实现了   System.IEquatable(Of T)接口和,   如果是这样,则返回EqualityComparer(Of   T)使用该实现。   否则,它返回一个   EqualityComparer(Of T)使用   覆盖Object.Equals和   Object.GetHashCode由T。

提供

因此,您可以在自定义类上实现IEquatable<T>,或覆盖Equals(和GetHashCode)方法,以便根据您需要的属性进行比较。或者你可以使用linq:

bool contains = list.Any(i => i.Id == obj.Id);

答案 2 :(得分:5)

您可以使用LINQ轻松完成此操作。

var result = MyCollection.Any(p=>p.myId == Id);
if(result)
{
     //something
}

答案 3 :(得分:2)

您可以覆盖Equals和GetHashCode,实施IEqualityComparer<MyObject>并在Contains调用中使用它,或使用Any等扩展方法

if (!myList.Any(obj => obj.Property == obj2.Property && obj.Property2 == obj2.Property2))
   myList.Add(obj2);

答案 4 :(得分:0)

您可以使用IEquatable<T>。在你的类中实现它,然后检查传递给Equals的T是否与this.Id具有相同的Id。我确信这适用于检查字典中的密钥,但我没有将它用于集合。

答案 5 :(得分:0)

首先使用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();

通过这种方式,您可以定义如何在不修改类的情况下计算Equality的方式。您也可以使用它来处理来自第三方库的对象,因为您无法修改它们的代码。