Есть ли способ найти свойства объекта в List < T > Использование Содержит?
-
22-07-2019 - |
Вопрос
Я бродил, как я могу узнать, существует ли объект в моем списке. Я добавляю " 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.