C# Действие лямбда-ограничение

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

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

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

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

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

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

5 ответов

Решение

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

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

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

Это поможет?

Вот мое мнение:

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

И ссылка:

12.3.3.11 Бросить заявления

Для утверждения stmt вида

throw expr;

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

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

delegate () { return XXX; }

где XXX это выражение

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

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

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

http://msdn.microsoft.com/en-us/library/ms364047(VS.80).aspx

показать, что у вас есть два варианта:

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#

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

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

Другие вопросы по тегам