Jika Anda tidak ingin menambahkan pustaka MoreLinq ke proyek Anda hanya untuk mendapatkan DistinctByfungsionalitas maka Anda bisa mendapatkan hasil akhir yang sama menggunakan kelebihan Distinctmetode Linq yang membutuhkan IEqualityComparerargumen.
Anda mulai dengan membuat kelas pembanding kesetaraan khusus generik yang menggunakan sintaks lambda untuk melakukan perbandingan kustom dua contoh kelas generik:
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);
}
}
Kemudian dalam kode utama Anda, Anda menggunakannya seperti ini:
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));
Voila! :)
Di atas mengasumsikan sebagai berikut:
- Properti
Person.Id adalah tipeint
- The
peoplekoleksi tidak mengandung unsur nol
Jika koleksi dapat berisi nol maka cukup tulis ulang lambda untuk memeriksa nol, misalnya:
Func<Person, Person, bool> areEqual = (p1, p2) =>
{
return (p1 != null && p2 != null) ? int.Equals(p1.Id, p2.Id) : false;
};
EDIT
Pendekatan ini mirip dengan yang ada di jawaban Vladimir Nesterovsky tetapi lebih sederhana.
Ini juga mirip dengan yang ada di jawaban Joel tetapi memungkinkan untuk logika perbandingan kompleks yang melibatkan beberapa properti.
Namun, jika objek Anda hanya dapat berbeda Idsaat itu maka pengguna lain memberikan jawaban yang benar bahwa semua yang perlu Anda lakukan adalah mengesampingkan implementasi default dari GetHashCode()dan Equals()di Personkelas Anda dan kemudian hanya menggunakan Distinct()metode Linq out-of-the-box untuk menyaring duplikat.