Pergunta

Eu estava vagando como posso descobrir se um objeto já existe na minha lista. Eu estou adicionando "newPerson" (instância da classe Person) em uma lista, mas verificar se o conteúdo newPerson / propriedades existe ou não na lista.

Esta peça funciona bem:

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

Em primeiro lugar, eu queria para simplificar / otimizar esse código feio acima. Então eu pensei sobre o uso do método Contém.

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

O segundo código acima não funciona, eu acho que ele está comparando referências objetos e não o conteúdo de objetos / propriedades.

Alguém aqui na Stackoverflow e em texto do link estava falando sobre o uso de uma classe que implementa IEqualityComparer. Eu dei-lhe uma tentativa, mas o código é muito maior agora! Algo como:

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

}

e usar este comparer:

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

Existe uma maneira pequena para encontrar propriedades de meu objeto em uma lista?

Foi útil?

Solução

Use Exists ou Any com um predicado:

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

Esse trabalho vontade com .NET 2.0 (e pode ser convertido em C # 2 utilizando um método anônimo). A solução mais 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;
}

Outras dicas

Parece que a sua classe Person deve implementar IEquatable . Sim, é (um pouco) mais código, mas então você não tem que repeti-lo cada vez que você quiser comparar 2 pessoa objetos.

A Contém método da lista usa o método do objeto por padrão é igual. Então, se você implementar IEquatable corretamente, você não tem que passar por um IEqualityComparer personalizado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top