以下に示すアプローチのいずれかを使用する方が簡単ではありません:)?ドメイン オブジェクトをいくつかのキーでグループ化し、以下のように FirstOrDefault を選択するだけです。これは、同様の質問に対する私の回答のコピーです:
一意の値を取得する - 元の回答
さらに興味深いオプションは、ドメインオブジェクトを取得し、Comparer がすぐに使用/操作できる他のオブジェクトを作成する Comparer アダプターを作成することです。コンパレーターに基づいて、以下のサンプルのようにカスタム linq 拡張機能を作成できます。それが役に立てば幸い :)
[TestMethod]
public void CustomDistinctTest()
{
// Generate some sample of domain objects
var listOfDomainObjects = Enumerable
.Range(10, 10)
.SelectMany(x =>
Enumerable
.Range(15, 10)
.Select(y => new SomeClass { SomeText = x.ToString(), SomeInt = x + y }))
.ToList();
var uniqueStringsByUsingGroupBy = listOfDomainObjects
.GroupBy(x => x.SomeText)
.Select(x => x.FirstOrDefault())
.ToList();
var uniqueStringsByCustomExtension = listOfDomainObjects.DistinctBy(x => x.SomeText).ToList();
var uniqueIntsByCustomExtension = listOfDomainObjects.DistinctBy(x => x.SomeInt).ToList();
var uniqueStrings = listOfDomainObjects
.Distinct(new EqualityComparerAdapter<SomeClass, string>(x => x.SomeText))
.OrderBy(x=>x.SomeText)
.ToList();
var uniqueInts = listOfDomainObjects
.Distinct(new EqualityComparerAdapter<SomeClass, int>(x => x.SomeInt))
.OrderBy(x => x.SomeInt)
.ToList();
}
カスタム比較アダプター:
public class EqualityComparerAdapter<T, V> : EqualityComparer<T>
where V : IEquatable<V>
{
private Func<T, V> _valueAdapter;
public EqualityComparerAdapter(Func<T, V> valueAdapter)
{
_valueAdapter = valueAdapter;
}
public override bool Equals(T x, T y)
{
return _valueAdapter(x).Equals(_valueAdapter(y));
}
public override int GetHashCode(T obj)
{
return _valueAdapter(obj).GetHashCode();
}
}
カスタム linq 拡張 (DistinctBy 拡張メソッドの定義):
// Embed this class in some specific custom namespace
public static class DistByExt
{
public static IEnumerable<T> DistinctBy<T,V>(this IEnumerable<T> enumerator,Func<T,V> valueAdapter)
where V : IEquatable<V>
{
return enumerator.Distinct(new EqualityComparerAdapter<T, V>(valueAdapter));
}
}
テスト ケースで使用されるドメイン クラスの定義:
public class SomeClass
{
public string SomeText { get; set; }
public int SomeInt { get; set; }
}