Comment puis-je effectuer une itération sur une collection et de modifier les valeurs avec LINQ méthodes d'extension?
Permet de dire que j'ai une collection de Messages qui a les propriétés "UserID" (int) et les "non Lus" (bool).
Comment puis-je utiliser LINQ extension des méthodes pour définir non Lus = false, pour tout Message dans la collection, dont le UserID = 5?
Donc, je sais que je peux faire quelque chose comme:
messages.Any(m => m.UserID == 5);
Mais, comment dois-je configurer le non Lus de la propriété de chacun de ceux avec une méthode d'extension ainsi?
Note: je sais que je ne devrais pas faire cela dans le code de production. Je suis simplement en train d'essayer d'apprendre un peu plus LINQ-fu.
- Est-il une raison pourquoi vous ne pouvez pas utiliser un régulier pour chaque itération sur la collection filtrée?
- pas de. Ce n'est pas le code de production. Je suis tout simplement avoir du plaisir et j'étais curieux de savoir si je pouvais faire une itération sur les éléments à l'aide de LINQ
- Juste pour la convention et la santé mentale souci, appelez ça de la lire, de ne pas Lus. si(m.Lire) est donc beaucoup plus facile à comprendre que si (!m.Non lus).
Vous devez vous connecter pour publier un commentaire.
En fait, c'est possible en utilisant uniquement le haut-LINQ méthodes d'extension sans
ToList
.Je crois que ce sera très similaire à un régulière
for
boucle. (Je n'ai pas vérifié)Ne pas vous ose le faire dans le code réel.
Comme un bonus supplémentaire, ce sera de retour le nombre d'utilisateurs de les modifier.
messages.Where(m => m.UserID == 5).ToList().ForEach(m => m.Unread = false);
Puis validez les modifications.
Any
renvoie un booléen, donc ce n'est pas exact - que vous auriez probablement souhaitezWhere
IEnumerable<bool>
. Tu veux direWhere
.Standard d'extension LINQ méthodes ne comprend pas d'effets secondaires visant méthodes. Cependant, vous pouvez les mettre en place vous-même ou utiliser de Réactive les Extensions .NET (Rx) comme ceci:
Comme il n'y a pas une méthode d'extension qui n'est un
ForEach
, vous êtes coincé soit avec l'aide d'un secondaire de la bibliothèque, ou de l'écriture de l'instruction foreach sur votre propre.Si vous voulez vraiment utiliser un Linq déclaration pour ce faire, créez une copie de la collection à l'aide de la
ToList()
méthode, l'accès à laForEach()
méthode de laList
type:ou placez le côté-effet dans un
Where()
déclaration:Dans les deux cas, je préfère utiliser l'explicite
foreach
boucle, car cela ne rend pas inutiles les copies et est plus claire que leWhere
hack.Select
de ne pas faire quoi que ce soit jusqu'à ce que le résultat est énuméré. Vous devriez appeler.Count()
surSelect
le retour de la valeur de la force de l'ensemble de la collection à être énumérées. Aussi, votre premierSelect
devrait en fait êtreWhere
.Where
de ne pas faire quoi que ce soit jusqu'à ce que sa valeur de retour est énuméré. Vous devez appeler.Count()
. Aussi, vous avez manqué une parenthèse fermante.Avec LINQ, vous ne pouvez pas parce que LINQ est un langage de requête/d'extension. Il y a cependant un projet appelé MoreLinq, qui définit une méthode d'extension appelé ForEach qui vous permet de passer d'une action qui sera effectuée sur chaque élément.
Donc, vous pouvez le faire avec MoreLinq:
Cordialement,
Oliver Hanappi
Cette réponse est dans l'esprit de fournir une solution. On pourrait créer une extension qui assure à la fois le prédicat (
Where
extension) pour éliminer les éléments et les actions nécessaires sur ces éléments.Ci-dessous est une extension nommée
OperateOn
qui est assez facile à écrire:Voici en action:
...
Vous devriez être capable de le faire dans un Select(), n'oubliez pas le lambda est un raccourci pour une fonction, de sorte que vous pouvez mettre autant de logique là-dedans que vous voulez, puis retour de l'élément en cours énumérés. Et... pourquoi ne pas vous faire cela dans le code de production?