Ограничение лямбда действия С#
Почему это выражение лямбда не компилируется?
Action a = () => throw new InvalidOperationException();
Конкуренция в порядке, но я бы очень признателен за ссылки на спецификацию языка С# или другую документацию.
И да, я знаю, что справедливо следующее и будет компилироваться:
Action a = () => { throw new InvalidOperationException(); };
Контекст, где я буду использовать что-то вроде этого, описан в этом сообщении в блоге.
Ответы
Ответ 1
Хм. У меня есть ответ, но это не здорово.
Я не считаю, что есть выражение "бросок". Там высказывание броска, но не просто выражение. Сравните это с "Console.WriteLine()", который является выражением вызова метода с типом void.
Как параллель, вы не можете иметь оператор switch, или оператор if и т.д. как тело лямбда самостоятельно. У вас может быть только выражение или блок (раздел 7.14).
Это любая помощь?
Ответ 2
Вот мой прием:
throw
- это выражение, а не выражение.
И ссылка:
12.3.3.11 Выдающие утверждения
Для утверждения stmt формы
throw expr;
определенное состояние присваивания v в начале выражения - это то же самое как определенное состояние присваивания v в начале строки.
Чтобы объяснить суть, возможно, следует подумать о том, что подразумевает выражение в конструкции С# лямбда. Это просто синтаксический сахар для:
delegate () { return XXX; }
где XXX
- выражение
Ответ 3
Все ссылки, которые я могу найти, отсюда:
http://msdn.microsoft.com/en-us/library/ms364047(VS.80).aspx#cs3spec_topic4
покажите, что у вас есть два варианта:
Action a = () => { throw new InvalidOperationException(); };
или
Action a = () => throw new InvalidOperationException()
Обратите внимание на отсутствие; в конце. Да, это тоже не имеет смысла. Примеры, которые они приводят в спецификации:
x => x + 1 // Implicitly typed, expression body
x => { return x + 1; } // Implicitly typed, statement body
(int x) => x + 1 // Explicitly typed, expression body
(int x) => { return x + 1; } // Explicitly typed, statement body
(x, y) => x * y // Multiple parameters
() => Console.WriteLine() // No parameters
Не знаю, как много помогает - я не могу сказать, в каком контексте вы его используете, а не помещать a; на конце не имеет смысла в С#
разница может заключаться в том, что это тело выражения - не утверждение - если оно не имеет {}. Это означает, что ваш бросок недействителен там, поскольку это утверждение, а не выражение!
Ответ 4
Вы не можете возвратить или выбросить из неметаллической лямбда.
Подумайте об этом таким образом... Если вы не предоставите {}, компилятор определит, каково ваше неявное возвращаемое значение. Когда вы throw
из лямбда, нет возвращаемого значения. Вы даже не возвращаете void
. Почему команда компилятора не справилась с этой ситуацией, я не знаю.
Ответ 5
Не большой сюрприз. Лямбда-выражения являются аспектом функционального программирования. Исключения являются аспектом процедурного программирования. Сетка С# между двумя стилями программирования не идеальна.