Bon, alors j'ai un énumérable et je souhaite obtenir des valeurs distinctes de celui-ci.
Utilisation de System.Linq
il y a, bien sûr, une méthode d'extension appelée Distinct
. Dans le cas simple, il peut être utilisé sans paramètres, comme :
var distinctValues = myStringList.Distinct();
C'est bien, mais si j'ai un énumérateur d'objets pour lequel je dois spécifier l'égalité, la seule surcharge disponible est :
var distinctValues = myCustomerList.Distinct(someEqualityComparer);
L'argument du comparateur d'égalité doit être une instance de IEqualityComparer<T>
. Je peux le faire, bien sûr, mais c'est un peu verbeux et, en fait, maladroit.
Ce que j'aurais attendu est une surcharge qui prendrait un lambda, disons un Func<T, T, bool>
:
var distinctValues = myCustomerList.Distinct((c1, c2) => c1.CustomerId == c2.CustomerId);
Quelqu'un sait-il si une telle extension existe, ou une solution de contournement équivalente ? Ou est-ce que je rate quelque chose ?
Alternativement, existe-t-il un moyen de spécifier un IEqualityComparer
en ligne (m'embarrasser) ?
Mise à jour
J'ai trouvé une réponse d'Anders Hejlsberg à une poste dans un forum MSDN sur ce sujet. Il dit :
Le problème que vous allez rencontrer est que lorsque deux objets se comparent identiques, ils doivent avoir la même valeur de retour GetHashCode (sinon la table de hachage utilisée en interne par Distinct ne fonctionnera pas correctement). Nous utilisons IEqualityComparer car il propose des implémentations compatibles de Equals et GetHashCode. compatibles de Equals et GetHashCode dans une seule interface.
Je suppose que c'est logique.
2 votes
Voir stackoverflow.com/questions/1183403/ pour une solution utilisant GroupBy
19 votes
Merci pour la mise à jour sur Anders Hejlsberg !
0 votes
Non, cela n'a pas de sens - comment deux objets qui contiennent des valeurs identiques peuvent-ils renvoyer deux codes de hachage différents ?
1 votes
Cela pourrait aider - solución para
.Distinct(new KeyEqualityComparer<Customer,string>(c1 => c1.CustomerId))
et expliquez pourquoi GetHashCode() est important pour fonctionner correctement.1 votes
Relié / duplicata possible de : Distinct() de LINQ sur une propriété particulière
0 votes
@G.Y C'est logique car l'égalité n'est pas absolue. On pourrait par exemple considérer "Hello" et "hello" comme égaux dans un contexte donné, et c'est là tout l'intérêt de pouvoir fournir son propre comparateur d'égalité : fournir une définition de l'égalité adaptée au domaine/contexte dans lequel on se trouve.
3 votes
Vous pouvez maintenant utiliser la méthode intégrée DistinctBy de .Net 6 comme suit DistinctBy(x => x.CustomerId) .