DistinctBy
機能を取得するためだけにMoreLinqライブラリをプロジェクトに追加したくない場合は、引数を受け取るLinqのDistinct
メソッドのオーバーロードを使用して同じ最終結果を取得できIEqualityComparer
ます。
まず、ラムダ構文を使用してジェネリッククラスの2つのインスタンスのカスタム比較を実行するジェネリックカスタム等価比較クラスを作成します。
public class CustomEqualityComparer<T> : IEqualityComparer<T>
{
Func<T, T, bool> _comparison;
Func<T, int> _hashCodeFactory;
public CustomEqualityComparer(Func<T, T, bool> comparison, Func<T, int> hashCodeFactory)
{
_comparison = comparison;
_hashCodeFactory = hashCodeFactory;
}
public bool Equals(T x, T y)
{
return _comparison(x, y);
}
public int GetHashCode(T obj)
{
return _hashCodeFactory(obj);
}
}
次に、メインコードで次のように使用します。
Func<Person, Person, bool> areEqual = (p1, p2) => int.Equals(p1.Id, p2.Id);
Func<Person, int> getHashCode = (p) => p.Id.GetHashCode();
var query = people.Distinct(new CustomEqualityComparer<Person>(areEqual, getHashCode));
出来上がり!:)
上記は次のことを前提としています。
- プロパティ
Person.Id
はタイプですint
people
コレクションは、任意のヌル要素が含まれていません
コレクションにnullが含まれる可能性がある場合は、ラムダを書き直してnullをチェックします。例:
Func<Person, Person, bool> areEqual = (p1, p2) =>
{
return (p1 != null && p2 != null) ? int.Equals(p1.Id, p2.Id) : false;
};
編集する
このアプローチは、ウラジミールネステロフスキーの回答に似ていますが、より単純です。
また、Joelの回答と似ていますが、複数のプロパティを含む複雑な比較ロジックが可能です。
あなたのオブジェクトがしかによって異なることができればしかし、Id
その後、別のユーザーは、あなたがする必要があるすべては、デフォルトの実装でオーバーライドしていること、正しい答えを与えたGetHashCode()
し、Equals()
自分の中にPerson
クラスをして、ちょうどすぐに使うDistinct()
フィルターにLINQの方法を重複を除外します。