2009-08-05 2 views
0

Ich war am Wandern, wie kann ich herausfinden, ob ein Objekt bereits in meiner Liste existiert. Ich füge "newPerson" (Instanz der Person-Klasse) in eine Liste ein, überprüfe aber, ob newPerson-Inhalte/-Eigenschaften in der Liste vorhanden sind oder nicht.Gibt es eine Möglichkeit, die Eigenschaften eines Objekts in der Liste <T> mit Contains zu finden?

Dieses Stück funktioniert:

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

Zunächst einmal wollte ich über diesen hässlichen Code vereinfachen/optimieren. Also habe ich über die Verwendung der Contains-Methode nachgedacht.

Der zweite Code oben funktioniert nicht, ich denke, es ist Vergleich von Objekten Referenzen und nicht Objekt Inhalte/Eigenschaften.

Jemand hier auf Stackoverflow und in link text sprach über die Verwendung einer Klasse, die IEqualityComparer implementiert. Ich habe es versucht, aber der Code ist jetzt viel größer! Etwas wie:

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

} 

und diesen Vergleich zu verwenden:

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

Gibt es einen kleinen Weg, um meine Eigenschaften des Objekt in einer Liste zu finden?

+0

Sollte es mit ".net" und "C#" Tag – jpbochi

Antwort

1

Verwenden Exists oder Any mit einem Prädikat:

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

, das mit .NET 2.0 funktioniert (und kann in C# 2 unter Verwendung einer anonyme Methode umgewandelt werden). Je mehr LINQy Lösung ist 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; 
} 
+0

Ja, ich werde es versuchen! Danke Jon! –

3

Es klingt wie Ihre Klasse Person IEquatable<Person> implementieren sollten. Ja, es ist (ein bisschen) mehr Code, aber dann müssen Sie es nicht jedes Mal wiederholen, wenn Sie Objekte mit 2 Personen vergleichen möchten.

Die Contains-Methode der Liste verwendet standardmäßig die Equals-Methode des Objekts. Wenn Sie also IEquatable korrekt implementieren, müssen Sie keinen benutzerdefinierten IEqualityComparer übergeben.

Verwandte Themen