Подтвердить что ты не робот

Ограничение лямбда действия С#

Почему это выражение лямбда не компилируется?

Action a = () => throw new InvalidOperationException();

Конкуренция в порядке, но я бы очень признателен за ссылки на спецификацию языка С# или другую документацию.

И да, я знаю, что справедливо следующее и будет компилироваться:

Action a = () => { throw new InvalidOperationException(); };

Контекст, где я буду использовать что-то вроде этого, описан в этом сообщении в блоге.

4b9b3361

Ответ 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

Не большой сюрприз. Лямбда-выражения являются аспектом функционального программирования. Исключения являются аспектом процедурного программирования. Сетка С# между двумя стилями программирования не идеальна.