有没有办法在List <t>中使用Contains?</t>查找对象的属性

时间:2009-08-05 19:50:43

标签: generics list find iequalitycomparer

我在徘徊,怎样才能知道我的列表中是否已存在某个对象。 我在List中添加“newPerson”(Person类的实例),但检查列表中是否存在newPerson内容/属性。

这件作品很好:

        List<Person> people = this.GetPeople();
        if (people.Find(p => p.PersonID  == newPerson.PersonID
                    && p.PersonName  == newPerson.PersonName) != null)
        {
            MessageBox.Show("This person is already in the party!");
            return;
        }

首先,我想简化/优化上面这个丑陋的代码。所以我想到了使用Contains方法。

        List<Person> people = this.GetPeople();
        if (people.Contains<Person>(newPerson)) //it doesn't work!
        {
            MessageBox.Show("This person is already in the party!");
            return;
        }

上面的第二个代码不起作用,我认为它是比较对象引用而不是对象内容/属性。

Stackoverflow和link text中的某个人正在谈论使用实现IEqualityComparer的类。我试了一下,但现在代码要大得多! 类似的东西:

    public class PersonComparer : IEqualityComparer<Person>
    {
    // Products are equal if their names and i numbers are equal.
    public bool Equals(Person x, Person y)
    {

        // Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) return true;

        // Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        // Check whether the products' properties are equal.
        return x.PersonID == y.PersonID && x.PersonName == y. PersonName;
    }

    // If Equals() returns true for a pair of objects,
    // GetHashCode must return the same value for these objects.

    public int GetHashCode(Person p)
    {
        // Check whether the object is null.
        if (Object.ReferenceEquals(p, null)) return 0;

        // Get the hash code for the Name field if it is not null.
        int hashPersonName = p.PersonName == null ? 0 : p.PersonName.GetHashCode();
        int hashPersonID = i.PersonID.GetHashCode();

        // Calculate the hash code for the i.
        return hashPersonName ^ hashPersonID;
    }

}

并使用此比较器:

        PersonComparer comparer = new PersonComparer();
        if (people.Contains<Person>(newPerson, comparer))
        {
            MessageBox.Show("This person is already in the party.");
            return;
        }

是否有更小的方法在List中查找对象的属性?

2 个答案:

答案 0 :(得分:3)

听起来你的Person类应该实现IEquatable<Person>。是的,这是(一点点)更多的代码,但是每次你想要比较2个人对象时你不必重复它。

列表的Contains方法默认使用对象的Equals方法。因此,如果正确实现IEquatable,则不必传递自定义IEqualityComparer。

答案 1 :(得分:1)

ExistsAny与谓词一起使用:

List<Person> people = this.GetPeople();
if (people.Exists(p => p.PersonID  == newPerson.PersonID
                       && p.PersonName  == newPerson.PersonName))
{  
    MessageBox.Show("This person is already in the party!");
    return;
}

这将适用于.NET 2.0(并且可以使用匿名方法转换为C#2)。 LINQy解决方案越Any

List<Person> people = this.GetPeople();
if (people.Any(p => p.PersonID  == newPerson.PersonID
                    && p.PersonName  == newPerson.PersonName))
{
    MessageBox.Show("This person is already in the party!");
    return;
}