11
votes

C # Question de l'Union Linq

Quelqu'un pourrait-il expliquer comment Union dans Linq fonctionne?

On dit qu'il fusionne deux séquences et supprime des doublons.

mais Puis-je personnaliser en quelque sorte le comportement de suppression en double - disons si je souhaite utiliser l'élément de la deuxième séquence en cas de duplicata ou de la première séquence . .

ou même si je souhaite en quelque sorte combiner ces valeurs dans la séquence qui en résulte?

Comment cela devrait-il être mis en œuvre?


Mise à jour < / h2>

Je suppose que j'ai décrit le problème de manière incorrecte, disons que nous avons une valeur: xxx

et le comparateur utilisé effectue un x.name == y.name chèque.

et disons que parfois je sais que je devrais prendre l'élément de la deuxième séquence, car il est quel que soit le champ est plus récent / meilleur que la quel que soit le champ de la première séquence.

Quoi qu'il en soit, je voudrais utiliser la section séquence1.Union (Séquence2) ou séquence2.Union (Séquence1) Variation des méthodes.

merci


0 commentaires

3 Réponses :


5
votes

Si les éléments sont des duplicats, cela n'a pas d'importance, quelle liste qu'ils sont extraites - à moins que votre comparateur d'égalité ne prenne toutes les propriétés de l'élément en tenant compte du cours.

S'ils ne sont pas vraiment duplicats, ils apparaîtront tous les deux dans l'union résultante.

mise à jour

de vos nouvelles informations au minimum, vous devez écrire un nouvel opérateur d'égalité qui prend quel que soit le compte . Vous ne pouvez pas simplement utiliser séquence1.Union (séquence2) ou séquence2.Union (Séquence1) Sauf si Tous Les éléments veulent prendre une séquence ou l'autre.

à l'extrême, vous devrez écrire votre propre méthode d'extension union union qui vous fait pour vous.


3 commentaires

Cela dépend de la façon dont vous définissez l'égalité ... Si le type implémente Iequatable (ou le comparateur d'égalité spécifique explicitement), il est possible que la comparaison ne prend pas en compte tous les membres.


@Thomas - cela a été impliqué dans ma réponse. Peut-être que je devrais le rendre explicite.


@Thomas - Mon édition a été invitée par votre commentaire mais dans la fenêtre de 5 minutes;)



15
votes

Vous pouvez utiliser second.union (premier) au lieu de premier.Union (deuxième) . De cette façon, il conservera les éléments de deuxième plutôt que les éléments de premier .


0 commentaires

7
votes

Lorsque l'objet renvoyé par cette méthode est énuméré, Union énumère d'abord et deuxième dans cet ordre et donne chaque élément qui n'a pas encore été donné.
http://msdn.microsoft.com/en-us/library/bb341731.aspx < / p>

de sorte que les éléments de la séquence que vous utilisez comme paramètre gauche prennent la priorité sur les éléments du paramètre droit.

La chose importante à ce sujet est que c'est bien défini et documenté le comportement et non seulement un détail de mise en œuvre pouvant changer dans la prochaine version de .NET.

comme une note latérale lorsque vous implémentez un IequalityComparer Il est important d'utiliser cohérent égale et gethashcode . Et dans ce cas, je préfère approfondir explicitement un comparateur d'égalité à la méthode de l'Union au lieu d'avoir le égal de l'objet lui-même renvoyer true pour des objets qui ne sont pas identiques à tous les fins .


1 commentaires

Merci, ceci est l'information requise: spécifiquement, la confiance que ce qui aurait pu être "comportement mystérieux noire" est en fait documenté et ne changera pas sans fanfare - vraisemblablement, ne changera pas du tout.