为什么这个lambda表达式不能编译?
Action a = () => throw new InvalidOperationException();
猜想很好,但我非常感谢对C#语言规范或其他文档的引用。
是的,我知道以下内容有效并将编译:
Action a = () => { throw new InvalidOperationException(); };
在this blog post上描述了我将使用类似内容的上下文。
答案 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#网格并不完美。