2010-02-12 5 views
7

Est-ce que quelqu'un sait s'il est possible de quitter un ForEach générique qui utilise lambda? par exemple.C# exit générique ForEach qui utilise lambda

someList.ForEach(sl => 
    { 
    if (sl.ToString() == "foo") 
     break; 

    // continue processing sl here 
    // some processing code 
    } 
); 

Ce code ne sera pas compilé. Je sais que je pourrais utiliser une foreach régulière mais pour la cohérence je veux utiliser lambda.

Merci beaucoup.

+0

Y at-il une raison pour laquelle cela DOIT être fait de cette façon? Je me suis toujours méfié de «casser». En dehors d'un boîtier de commutation, je n'ai jamais vu besoin de les utiliser. – FrustratedWithFormsDesigner

+5

J'utilise 'break' et' continue' beaucoup. Parfois, vous ne voulez pas que le corps de la boucle s'exécute tout au long, et 'break' /' continue' simplifie le code. –

+0

Y a-t-il une raison pour laquelle vous préférez une expression lambda? –

Répondre

17

Bien sûr. Mais d'abord, notez que je recommande contre cela; Je dis qu'un opérateur de séquence ne devrait pas avoir d'effet secondaire, et une déclaration devrait avoir un effet secondaire. Si vous faites quelque chose dans ForEach lambda, alors faites-en une déclaration dans le corps d'une boucle foreach plutôt que de la faire ressembler à un opérateur de séquence.

Cela dit, voici ce que vous faites. Tout d'abord, vous vous écrivez un ForEach qui fonctionne sur des séquences arbitraires, non pas des listes juste:

public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action) 
{ 
    foreach(var item in sequence) action(item); 
} 

Et maintenant, vous écrivez votre pause comme ceci:

someList 
    .TakeWhile(x=>x.ToString() != "foo") 
    .ForEach(sl=> 
    {/*your action here*/}); 
+0

Bart De Smet a fait plusieurs choses de type 'ForEach' commençant par' if': http://community.bartdesmet.net/blogs/bart/archive/2009/07/11/bart-s-control-library-not- Qu'est-ce-que-tu-penses-il-fait-partie-0.aspx. –

7

De MSDN

ci-dessous les règles s'appliquent à la variable portée en expressions lambda:

snip

Une expression lambda ne peut pas contenir une déclaration goto, déclaration rupture ou instruction continue dont l'objectif est en dehors du corps ou dans le corps d'une fonction anonyme contenu.

Je ne sais pas si cela aide compte tenu du code que vous avez posté. La citation pertinente est à la fin de l'article MSDN.

+0

La réponse la plus pertinente et complète pour le moment. J'aime ça! –

1

Attention: le code ci-dessous ne doit pas être pris au sérieux et est uniquement fourni à des fins de divertissement!

Vous pouvez « simuler » un Poursuivons avec un retour rapide comme celui-ci:

Enumerable.Range(1, 20) 
      .ForEach(n => 
       { 
        if (n == 10) return; 
        Console.WriteLine("This is not 10: {0}", n); 
       }); 

Cela dit, je pense que les effets secondaires dans de lambda sont un signe que vous faites mal. Utilisez plutôt une foreach appropriée. Ou quelque chose comme TakeWhile, comme Eric l'a déjà aimablement démontré.

0

Que pensez-vous de cela?

 Enumerable.Range(1, 10) 
     .Where(x => x % 2 != 0) 
     .ToList() 
     .ForEach(x => Console.WriteLine(x));