2012-01-30 6 views
4

У меня есть список, и я делаю list.ForEach(l => { ... something ...}). Теперь, при определенном условии, мне нужно остановить итерирование по списку, но break не работает - я получаю ошибку «Control cannot leave the body of an anonymous method or lambda expression».Как покинуть тело выражения лямбды

Любая идея, как преодолеть это ограничение?

ответ

7

Использование только break здесь не будет работать, потому что лямбда выполняется в другом методе, чем цикл for. Оператор break полезен только для выхода из локальных по отношению к текущей функции конструкций.

Для поддержки стирания разрыва вам необходимо добавить перегрузку ForEach, где делегат может указать через возвращаемое значение, которое должно выполняться при выполнении цикла. Например

public static void ForEach<T>(this IEnumerable<T> enumerable, Func<T, bool> func) { 
    foreach (var cur in enumerable) { 
    if (!func(cur)) { 
     break; 
    } 
    } 
} 

Теперь потребитель этого ForEach метода можно указать break путем возврата false из предоставленного обратного вызова

myCollection.ForEach(current => { 
    if (someCondition) { 
    // Need to break 
    return false; 
    } 
    // Keep going 
    return true; 
} 
6

Выражение лямбда работает точно так же, как метод.
Он может return всякий раз, когда вы хотите.

Однако List.ForEach не предлагает возможности преждевременной остановки итерации.
Если вам нужно break, вы просто используете обычный цикл foreach.

+0

А что бы вы сделали в лее из 'continue', если вам нужно условно пропустить итерация - она ​​тоже не работает. – Andrey

+0

У вас есть лямбда, возвращающая логическое значение в вашем цикле, и, если оно вернет false, вы сломаетесь. –

+3

'return' здесь работает как' continue', а не как 'break'. – porges

1

Вы не можете остановить итерацию в пределах лямбда ForEach, так как у вас нет контроля над внешним циклом, который вызывает лямбда. В этот момент почему бы вам не использовать обычный цикл foreach и инструкцию break - это было бы гораздо более читаемым для этого случая.

+0

Единственная причина, по которой я использую лямбда, - это то, что мне нравится использовать лямбда, и это единственная причина, по которой она была добавлена ​​в C# - удобство. Вы правы - если это не работает для определенного случая, я буду использовать foreach или что-нибудь применимое; Мне просто интересно, есть ли способ по-прежнему использовать его. Вот и все, просто любопытный ум :) – Andrey

+0

@ Ответ JaredPar будет делать трюк тогда – BrokenGlass

Смежные вопросы