0

リストにオブジェクトがすでに存在するかどうかを確認するにはどうすればよいか迷っていました。リストに「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;
        }

上記の2番目のコードは機能しません。オブジェクトのコンテンツ/プロパティではなく、オブジェクトの参照を比較していると思います。

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

リスト内のオブジェクトのプロパティを見つけるためのより小さな方法はありますか?

4

2 に答える 2

3

Person クラスはIEquatable<Person>を実装する必要があるようです。はい、(少し) コードが増えますが、2 つの人物オブジェクトを比較するたびに繰り返す必要はありません。

リストの Contains メソッドは、既定でオブジェクトの Equals メソッドを使用します。したがって、IEquatable を正しく実装すれば、カスタム IEqualityComparer を渡す必要はありません。

于 2009-08-05T19:55:10.370 に答える
1

ExistsorAnyを述語とともに使用します。

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;
}
于 2009-08-05T19:54:55.720 に答える