Есть ли способ найти свойства объекта в List < T > Использование Содержит?

StackOverflow https://stackoverflow.com/questions/1235370

Вопрос

Я бродил, как я могу узнать, существует ли объект в моем списке. Я добавляю " 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 и в тексте ссылки говорил об использовании класса, который реализует 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;
        }

Есть ли меньший способ найти свойства моего объекта в списке?

Это было полезно?

Решение

Используйте Exists или Any с предикатом:

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;
}

Другие советы

Похоже, ваш класс Person должен реализовать IEquatable < Person > . Да, это (немного) больше кода, но тогда вам не нужно повторять его каждый раз, когда вы хотите сравнить объекты двух человек.

Метод списка содержит метод Equals объекта по умолчанию. Поэтому, если вы правильно реализуете IEquatable, вам не нужно передавать пользовательский IEqualityComparer.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top