L'utilisation d'un délégué pour l'égalité comparer pour LINQ Distinct()
J'ai une LINQ Distinct() instruction qui utilise mon propre comparer, comme ceci:
class MyComparer<T> : IEqualityComparer<T> where T : MyType
{
public bool Equals(T x, T y)
{
return x.Id.Equals(y.Id);
}
public int GetHashCode(T obj)
{
return obj.Id.GetHashCode();
}
}
...
var distincts = bundle.GetAllThings.Distinct(new MyComparer<MySubType>());
C'est toute fine et dandy et fonctionne comme je veux. Par curiosité, j'ai besoin de définir ma propre Comparer, ou puis-je le remplacer par un délégué? J'ai pensé que je devrais être en mesure de faire quelque chose comme ceci:
var distincts = bundle.GetAllThings.Distinct((a,b) => a.Id == b.Id);
Mais cela ne veut pas compiler. Est-il une astuce?
- Vous devriez avoir un
ReferenceEquals
les contrôles contre le nul surx
ety
dans votreEquals
mise en œuvre.
Vous devez vous connecter pour publier un commentaire.
Distinctes prend un IEqualityComparer comme deuxième argument, de sorte que vous aurez besoin d'un IEqualityComparer. Il n'est pas trop dur de faire un générique qui va prendre un délégué, si. Bien sûr, cela a probablement déjà été mis en œuvre dans certains endroits, tels que MoreLINQ suggéré dans l'une des autres réponses.
Vous pourriez mettre en œuvre quelque chose comme ceci:
Qui vous donne la syntaxe:
Ou, si vous vous sentez qu'il est plus clair de cette façon:
TIdentity
devrait avoir unIEquatable<TIdentity>
contrainte, et par conséquent, utiliser leidentitySelector(x).Equals(identitySelector(y))
à la place. C'est dans le but de prévenir une référence de comparaison en raison de génériques pas de déduire le type construit les surcharges.Il est malheureux que les
Distinct
ne vient pas avec une telle surcharge, donc ce que vous avez est une bonne option.Avec MoreLinq, vous pouvez utiliser le
DistinctBy
opérateur.Vous pourriez également envisager d'écrire un générique
ProjectionEqualityComparer
qui peut tourner à la appropriée délégué dans unIEqualityComparer<T>
mise en œuvre, comme l'un de ceux énumérés ici.Ce lien montre comment créer une extension de la méthode pour être en mesure d'utiliser Distinct de la manière que vous avez donné. Vous aurez besoin d'écrire deux
Distinct
les méthodes d'extension, et unIEqualityComparer
.Voici le code à partir du site:
Voici mon pervers, sale peu de vanille en C# astuce: