C # Действие лямбда-ограничение - PullRequest
16 голосов
/ 31 октября 2008

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

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

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

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

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

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

Ответы [ 5 ]

19 голосов
/ 31 октября 2008

Хм. У меня есть ответ, но он не велик.

Я не верю, что есть "бросок" выражения . Есть оператор throw , но не просто выражение. Сравните это с Console.WriteLine (), который является выражением вызова метода с типом void.

В качестве параллели вы не можете иметь оператор switch, или оператор if и т. Д. В качестве тела лямбды. Вы можете иметь только выражение или блок (раздел 7.14).

Это какая-то помощь?

15 голосов
/ 31 октября 2008

Вот мой дубль:

throw - это утверждение, а не выражение.

И ссылка:

12.3.3.11 Бросок операторов

Для оператора stmt вида

throw expr;

состояние определенного присваивания v в начале expr то же самое как состояние определенного присваивания V в начале stmt.

Чтобы объяснить суть, возможно, следует подумать о том, что подразумевает выражение в лямбда-конструкции C #. Это просто синтаксический сахар для:

delegate () { return XXX; }

где XXX - выражение

1 голос
/ 31 октября 2008

Вы не можете вернуться или бросить из не ограниченной области лямбда.

Подумайте об этом так ... Если вы не предоставите {}, компилятор определит, какое у вас неявное возвращаемое значение. Когда вы throw из лямбды, возвращаемое значение отсутствует. Вы даже не возвращаете void. Почему команда компиляторов не справилась с этой ситуацией, я не знаю.

1 голос
/ 31 октября 2008

Все ссылки, которые я могу найти здесь:

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

Не знаю, сколько это помощи - я не могу сказать, в каком контексте вы ее используете, а не ставите; в конце нет смысла в C #

разница может заключаться в том, что это тело выражения, а не утверждение, если оно не имеет {}. Это означает, что ваш бросок там недопустим, так как это утверждение, а не выражение!

0 голосов
/ 31 октября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...