2

重複を防止しようとしているときにac#ジェネリックリストに値を追加していますが、成功していません。以下のこのコードが機能しない理由を知っている人はいますか?

ここに簡単なクラスがあります:

public class DrivePairs
{
    public int Start { get; set; }
    public int End { get; set; }
}

そして、これが上記のクラスのジェネリックリストを返そうとする私のメソッドです:

ArrayList found = DriveRepository.GetDriveArray(9, 138);
List<DrivePairs> drivePairs = new List<DrivePairs>();
foreach (List<int> item in found)
{
    int count = item.Count;
    if (count > 1)
    {
        for (int i = 0; i < (count - 1); i++)
        {
            DrivePairs drivePair = new DrivePairs();
            drivePair.Start = item[i];
            drivePair.End = item[i + 1];

            if (!drivePairs.Contains(drivePair))
                drivePairs.Add(drivePair);
        }
    }
}
drivePairs = drivePairs.Distinct().ToList();

ご覧のとおり、私にはがありArrayList、各行には。が含まれていList<int>ます。私がやっていることは、それぞれを調べて、ペアだけを含むリストに追加することです。たとえば、List<int>が含まれている場合[1,3,6,9]、ペアリストに3つのエントリを追加します。

[1,3]
[3,6]
[6,9]

重複を認識しないことを除けば、すべて正常に機能します。私はこの行で十分だと思いました:

if (!drivePairs.Contains(drivePair))
    drivePairs.Add(drivePair);

しかし、それはそれらすべてを追加し続けます。最後にを追加しDistinct()ても削除されません。それらをに追加しようとしましたHashSetが、それでもすべての重複が含まれています。

重複が検出されない理由を知っている人はいますか?

4

6 に答える 6

6

クラスで等式DrivePairsが指定されていないため、Containsメソッドは参照の等式を使用します。Startとの両方を使用して同等性を判断するEqualsメソッドを追加するEndと、コードが機能することがわかります。

参照:同等性の比較(C#プログラミングガイド)

于 2012-05-04T09:05:55.290 に答える
3

List.Containsメソッド

このメソッドは、オブジェクトのIEquatable.EqualsメソッドのT(リスト内の値のタイプ)の実装によって定義されているように、デフォルトの等式比較子を使用して等式を判別します。

DrivePairsクラスを変更する

    public class DrivePairs: IEquatable<DrivePairs>
    {
        public int Start { get; set; }
        public int End { get; set; }

        public bool Equals(DrivePairs other)
        {
            return (this.Start == other.Start && this.End == other.End)
        }
    } 

参照: http: //msdn.microsoft.com/en-us/library/bhkz42b3.aspx

お役に立てれば

于 2012-05-04T09:11:52.653 に答える
1

新しいList<int>オブジェクトを作成しています-これらは異なるオブジェクトであり、互いに比較すると、同じ値が(同じまたは異なる順序で)含まれている場合でも、参照型のデフォルトの比較方法は参照比較であるため、異なるものとして評価されます。

アプリケーションが必要とする方法で等しいリストを識別するカスタム比較子を作成する必要があります。

于 2012-05-04T09:08:24.230 に答える
1

私はColinを答えとしてマークしましたが、誰かが使用する場合に備えて、ここにコードを示します。

平等比較:

    public class EqualityComparer : IEqualityComparer<DrivePairs>
    {
        public bool Equals(DrivePairs x, DrivePairs y)
        {
            return x.StartHub.Equals(y.Start);
        }

        public int GetHashCode(DrivePairs obj)
        {
            return obj.Start.GetHashCode();
        }
    }

およびコントローラー内:

IEqualityComparer<DrivePairs> customComparer = new EqualityComparer();

IEnumerable<DrivePairs> distinctDrivePairs = drivePairs.Distinct(customComparer);
drivePairs = distinctDrivePairs.ToList();

すべてのヘルプとコメントをありがとう

于 2012-05-04T09:29:55.563 に答える
0

DrivePairsクラスタイプは参照型です(参照型と値型の概念を覚えておいてください)。したがって、DrivePairs変数がすでにリストコレクションに追加されているかどうかを確認すると、すべてのDrivePairs変数が他の変数とは異なるメモリ位置を持っているため、falseが返されます。

Dictionary、StringDictionary、またはその他のKey-Valueペアコレクションを使用してみてください。それは間違いなく機能します。

于 2012-05-04T09:07:21.750 に答える
0

私はそれをテストしていませんが、デフォルトの同等性テストはそれが同じインスタンスであるかどうかだと思います。Equalsメソッドをオーバーライドして、プロパティを使用するようにしてください。

于 2012-05-04T09:08:07.557 に答える