14

Linq に関する本を読んでいて、Distinct メソッドに比較子を使用するオーバーロードがあることがわかりました。これは、コレクションから個別のエンティティを取得したいが、他のプロパティが異なっていてもエンティティ ID で比較したいという問題に対する良い解決策です。

この本によると、Gribulator エンティティがあれば、このような比較子を作成できるはずです...

private class GribulatorComparer : IComparer<Gribulator> {
  public int Compare(Gribulator g1, Gribulator g2) {
    return g1.ID.CompareTo(g2.ID);
  }
}

...そして、このように使用します...

List<Gribulator> distinctGribulators
  = myGribulators.Distinct(new GribulatorComparer()).ToList();

ただし、これにより次のコンパイラエラーが発生します...

'System.Collections.Generic.List' には、'Distinct' と最適な拡張メソッド オーバーロード 'System.Linq.Enumerable.Distinct(System.Collections.Generic.IEnumerable, System.Collections.Generic.IEqualityComparer)' の定義が含まれていません。いくつかの無効な引数があります

引数 2: 'LinqPlayground.Program.GribulatorComparer' から 'System.Collections.Generic.IEqualityComparer' に変換できません

私は少し調べて、このようなコードを使用する例をたくさん見てきましたが、コンパイラ エラーについての苦情はありません。

私は何を間違っていますか?また、これはこれを行うための最良の方法ですか?ここでは 1 回限りの解決策が必要なので、エンティティ自体のコードの変更を開始したくありません。エンティティはそのままにしておきたいのですが、ここだけは ID だけで比較してください。

助けてくれてありがとう。

4

1 に答える 1

18

比較子を として実装しています。LINQIComparer<T>メソッドのオーバーロードには、次の実装が必要ですIEqualityComparer

private class GribulatorComparer : IEqualityComparer<Gribulator> {
  public bool Equals(Gribulator g1, Gribulator g2) {
    return g1.ID == g2.ID;
  }
}

編集:

明確にするために、IComparerインターフェイスはソートに使用できます。これは、基本的にCompare()メソッドが行うことです。

このような:

items.OrderBy(x => new ItemComparer());

private class ItemComparer : IComparer<Item>
{
    public int Compare(Item x, Item y)
    {
        return x.Id.CompareTo(y.Id)
    }
}

その比較子を使用してコレクションを並べ替えますが、LINQ は単純なフィールド (int Id など) に対してそれを行う方法を提供します。

items.OrderBy(x => x.Id);
于 2012-11-11T14:31:27.597 に答える