C'è un modo per trovare le proprietà di un oggetto in Elenco < T > usando contiene?
-
22-07-2019 - |
Domanda
Stavo vagando come posso scoprire se un oggetto esiste già nella mia lista. Sto aggiungendo " newPerson " (istanza della classe Person) in un Elenco, ma verificando se i contenuti / le proprietà di newPerson esistono o meno nell'elenco.
Questo pezzo funziona benissimo:
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;
}
Prima di tutto, volevo semplificare / ottimizzare questo brutto codice sopra. Quindi ho pensato di usare il metodo 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;
}
Il secondo codice sopra non funziona, penso che paragona i riferimenti agli oggetti e non i contenuti / le proprietà degli oggetti.
Qualcuno qui su Stackoverflow e in link text stava parlando dell'uso di una classe che implementa IEqualityComparer. Ci ho provato, ma ora il codice è molto più grande! Qualcosa del tipo:
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 per utilizzare questo comparatore:
PersonComparer comparer = new PersonComparer();
if (people.Contains<Person>(newPerson, comparer))
{
MessageBox.Show("This person is already in the party.");
return;
}
Esiste un modo più piccolo per trovare le proprietà del mio oggetto in un elenco?
Soluzione
Usa esiste
o Any
con un predicato:
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;
}
Funzionerà con .NET 2.0 (e può essere convertito in C # 2 usando un metodo anonimo). La soluzione LINQy più è 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;
}
Altri suggerimenti
Sembra che la tua classe Person dovrebbe implementare IEquatable < Person > . Sì, è (un po ') più codice, ma non è necessario ripeterlo ogni volta che si desidera confrontare oggetti di 2 persone.
Il metodo Contiene dell'elenco utilizza il metodo Equals dell'oggetto per impostazione predefinita. Pertanto, se si implementa IEquatable correttamente, non è necessario passare un IEqualityComparer personalizzato.