Existe-t-il un moyen de rechercher les propriétés d'un objet dans List < T > en utilisant Contains?

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

Question

Je me demandais comment puis-je savoir si un objet existe déjà dans ma liste? J'ajoute " newPerson " (instance de la classe Person) dans une liste, mais en vérifiant si newPerson content / properties existe ou non dans la liste.

Cette pièce fonctionne bien:

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

Tout d’abord, je voulais simplifier / optimiser ce code laid ci-dessus. J'ai donc pensé à utiliser la méthode 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;
        }

Le deuxième code ci-dessus ne fonctionne pas, je pense qu'il compare les références d'objets et non le contenu / les propriétés des objets.

Quelqu'un ici sur Stackoverflow et dans texte du lien parlait d'utiliser une classe qui implémente IEqualityComparer. J'ai essayé, mais le code est beaucoup plus gros maintenant! Quelque chose comme:

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

}

et utiliser ce comparateur:

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

Existe-t-il un moyen plus simple de rechercher les propriétés de mon objet dans une liste?

Était-ce utile?

La solution

Utiliser Existe ou Tout avec un prédicat:

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

Cela fonctionnera avec .NET 2.0 (et peut être converti en C # 2 en utilisant une méthode anonyme). Plus la solution LINQy est 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;
}

Autres conseils

Il semble que votre classe Person devrait implémenter IEquatable < Personne > . Oui, c'est (un peu) plus de code, mais vous n'avez pas besoin de le répéter chaque fois que vous voulez comparer des objets à deux personnes.

La méthode Contains de la liste utilise la méthode Equals de l'objet par défaut. Donc, si vous implémentez correctement IEquatable, vous ne devez pas transmettre un IEqualityComparer personnalisé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top