C#动作lambda限制

时间:2008-10-31 17:19:45

标签: c# compiler-construction lambda

为什么这个lambda表达式不能编译?

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

猜想很好,但我非常感谢对C#语言规范或其他文档的引用。

是的,我知道以下内容有效并将编译:

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

this blog post上描述了我将使用类似内容的上下文。

5 个答案:

答案 0 :(得分:19)

嗯。我有答案,但不是很好。

我不相信有一个“扔”表达式。有一个throw 语句,但不只是一个表达式。将其与“Console.WriteLine()”进行比较,后者是一个带有void类型的方法调用表达式。

作为并行,你不能将switch语句或if语句等作为lambda的主体。您只能有表达式或块(第7.14节)。

这有什么帮助吗?

答案 1 :(得分:15)

这是我的看法:

throw是一个陈述,而不是表达。

参考:

  

12.3.3.11抛出语句

     

对于表单

的语句stmt      

throw expr;

     

v的明确赋值状态   在expr的开头是相同的   作为v的明确赋值状态   在stmt。的开始。

为了解释本质,或许应该考虑一个表达式在C#lambda构造中隐含的内容。它只是语法糖:

delegate () { return XXX; }

其中XXX是表达式

答案 2 :(得分:1)

我可以找到所有参考资料,从这里开始:

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

Dunno有多少帮助 - 我不知道你在使用它的上下文,而不是放一个;最后在C#中没有任何意义

差异可能是它是一个表达体 - 而不是一个声明 - 如果它没有{}。这意味着你的投掷在那里无效,因为它是一个陈述,而不是表达!

答案 3 :(得分:1)

你不能从没有范围的lambda返回或抛出。

以这种方式思考......如果您不提供{},编译器将确定您的隐式返回值是什么。当您从lambda中throw时,没有返回值。你甚至没有回归void。为什么编译器团队没有处理这种情况,我不知道。

答案 4 :(得分:0)

不是一个大惊喜。 Lambda表达式是功能编程的一个方面。例外是程序编程的一个方面。两种编程风格之间的C#网格并不完美。