c # выход универсального ForEach, использующего лямбду - PullRequest
7 голосов
/ 12 февраля 2010

Кто-нибудь знает, возможно ли выйти из универсального ForEach, использующего лямбду? например,

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

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

Этот код сам по себе не компилируется. Я знаю, что мог бы использовать обычный foreach, но для согласованности я хочу использовать лямбду.

Большое спасибо.

Ответы [ 4 ]

17 голосов
/ 12 февраля 2010

Конечно. Но сначала обратите внимание, что я рекомендую против этого; Я говорю, что оператор последовательности не должен иметь побочного эффекта, а оператор должен иметь побочный эффект. Если вы делаете что-то в этой лямбде ForEach, то сделайте это в теле цикла foreach, а не в виде оператора последовательности.

Тем не менее, вот что вы делаете. Во-первых, вы пишете себе ForEach, который работает с произвольными последовательностями, а не только со списками:

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

А теперь вы пишете свой перерыв так:

someList
    .TakeWhile(x=>x.ToString() != "foo")
    .ForEach(sl=>
    {/*your action here*/});
8 голосов
/ 12 февраля 2010

С MSDN

Следующие правила применяются к переменной область в лямбда-выражениях:

snip

Лямбда-выражение не может содержать оператор goto, оператор break или продолжить заявление, целью которого является вне тела или в теле содержал анонимную функцию.

Не знаю, поможет ли это, учитывая код, который вы разместили. Соответствующая цитата приведена в конце статьи MSDN.

1 голос
/ 12 февраля 2010

Предупреждение: код ниже не следует воспринимать всерьез и предоставляется только для развлекательных целей!

Вы можете «симулировать» продолжение с ранним возвратом, как это:

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

Тем не менее, я думаю, что побочные эффекты в лямбде являются признаком того, что вы делаете это неправильно. Вместо этого используйте правильный foreach. Или что-то вроде TakeWhile, как любезно продемонстрировал Эрик.

0 голосов
/ 12 февраля 2010

Как насчет этого?

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