5

オブジェクトを含むリストがありますが、これらのオブジェクトはリスト内で一意ではありません。別のリストでそれらを一意にするために、このコードを書きました。

 foreach (CategoryProductsResult categoryProductsResult in categoryProductsResults.Where(categoryProductsResult => !resultSet.Contains(categoryProductsResult)))
 {
    resultSet.Add(categoryProductsResult);
 }

しかし、最終的にresultSetはcategoryProductsResultsと同じです。

categoryProductsResult の 2 行目:

ここに画像の説明を入力

結果セットの最初の行:

ここに画像の説明を入力

ご覧のとおり、resultSet の最初の行と categoryProductsResult の 2 番目の行は同じですが、2 番目の行が resultSet に追加されます。

何か提案はありますか?

4

5 に答える 5

13

ContainsEqualsクラスはand をオーバーライドしないため、参照を比較するデフォルトの比較子を使用しますGetHashCode

class CategoryProductsResult
{
    public string Name { get; set; }
    // ...

    public override bool  Equals(object obj)
    {
        if(obj == null)return false;
        CategoryProductsResult other = obj as CategoryProductsResult;
        if(other == null)return false;
        return other.Name == this.Name;
    }

    public override int  GetHashCode()
    {
         return Name.GetHashCode();
    }
}

これで、次のように簡単に使用できます。

resultSet = categoryProductsResults.Distinct().ToList();
于 2013-02-22T09:24:34.240 に答える
3

List は EqualityComparer.Default によって返された比較子を使用し、そのドキュメントに従って:

Default プロパティは、型 T が System.IEquatable(Of T) インターフェイスを実装しているかどうかを確認し、実装されている場合は、その実装を使用する EqualityComparer(Of T) を返します。それ以外の場合は、T によって提供される Object.Equals および Object.GetHashCode のオーバーライドを使用する EqualityComparer(Of T) を返します。

そのため、カスタム クラスに IEquatable を実装するか、Equals (および GetHashCode) メソッドをオーバーライドして、必要なプロパティによる比較を行うことができます。または、linq を使用することもできます。

bool contains = list.Any(i => i.Id == obj.Id);

于 2013-02-22T09:23:15.153 に答える
1

それぞれcategoryProductsResultが互いに異なっています。それはあなたがここで見ることができるもののようなものです. より単純なものが必要で、ProductId が一意の識別子である場合。以下のコードを実行するだけです。

foreach (CategoryProductsResult categoryProductsResult in categoryProductsResults.Where(categoryProductsResult => resultSet.ProductId !=categoryProductsResult.ProductId)
{
    resultSet.Add(categoryProductsResult);
}
于 2013-02-22T09:27:14.673 に答える
0

リスト内の参照オブジェクトは、ハッシュ コードによってインデックス付けされます。そのContainsため、同じハッシュ コードを持つ参照オブジェクトを見つけることはありません (クラスでGetHashCodeandの実装をオーバーライドしない限り.Equals

このSOの答えは説明しています。

于 2013-02-22T09:22:53.153 に答える
0

反復ごとに、現在のアイテムがターゲット リストに含まれているかどうかを確認する必要があります。現在、ループの開始時に 1 回チェックしています。これは、アイテムがターゲット リストにないことを意味します。

私はDistinctがすでにあなたが望むことをしていると思います.あなた自身のループの代わりにこの拡張機能を使いたいかもしれません.

于 2013-02-22T09:24:53.993 に答える