考虑以下来源:
static void Main(string[] args)
{
bool test;
Action lambda = () => { test = true; };
lambda();
if (test)
Console.WriteLine("Ok.");
}
它应该编译,对吧?好吧,事实并非如此。我的问题是:根据 C# 标准,这段代码应该编译还是编译器错误?
错误信息:
Use of unassigned local variable 'test'
注意:我知道,如何修复错误,我部分知道,为什么会发生。然而,局部变量是无条件赋值的,我想编译器应该注意到这一点,但它没有。我想知道,为什么。
答案评论:C# 允许声明未分配的变量,这实际上非常有用,即。
bool cond1, cond2;
if (someConditions)
{
cond1 = someOtherConditions1;
cond2 = someOtherConditions2;
}
else
{
cond1 = someOtherConditions3;
cond2 = someOtherConditions4;
}
编译器正确编译了这段代码,我认为,不分配变量实际上会使代码好一点,因为:
- 它告诉读者,值是稍后分配的(主要可能是在以下条件语句中)
- 强制程序员在内部条件的所有分支中分配变量(如果从一开始就是这段代码的目的),因为如果其中一个分支没有分配其中一个,编译器将拒绝编译代码。
边缘: 这更有趣。考虑 C++ 中的相同示例:
int main(int argc, char * argv[])
{
bool test;
/* Comment or un-comment this block
auto lambda = [&]() { test = true; };
lambda();
*/
if (test)
printf("Ok.");
return 0;
}
如果您注释掉该 block ,编译将以警告结束:
main.cpp(12): warning C4700: uninitialized local variable 'test' used
但是,如果您删除注释,编译器将不会发出任何警告。在我看来,它能够确定是否最终设置了变量。
最佳答案
My question is: according to C# standard, should this code compile or is this a compiler bug?
这不是错误。
C# Language Specification 的第 5.3.3.29 节(4.0) 概述了关于匿名函数的明确赋值规则,包括 lambda 表达式。我会在这里发布。
5.3.3.29 Anonymous functions
For a lambda-expression or anonymous-method-expression expr with a body (either block or expression) body:
The definite assignment state of an outer variable v before body is the same as the state of v before expr. That is, definite assignment state of outer variables is inherited from the context of the anonymous function.
The definite assignment state of an outer variable v after expr is the same as the state of v before expr.
The example
delegate bool Filter(int i); void F() { int max; // Error, max is not definitely assigned Filter f = (int n) => n < max; max = 5; DoWork(f); }
generates a compile-time error since max is not definitely assigned where the anonymous function is declared. The example
delegate void D(); void F() { int n; D d = () => { n = 1; }; d(); // Error, n is not definitely assigned Console.WriteLine(n); }
also generates a compile-time error since the assignment to n in the anonymous function has no affect on the definite assignment state of n outside the anonymous function.
您可以看到这如何适用于您的具体示例。变量 test
没有在 lambda 表达式声明之前专门赋值。在执行 lambda 表达式之前,它不会被专门分配。并且在lambda表达式执行完成后并没有具体赋值。按照规则,编译器不会认为变量在 if
语句中被读取时已明确赋值。
至于为什么,我只能重复我读过的关于此事的内容,并且只能重复我记得的内容,因为我无法生成链接,但 C# 不会尝试这样做,因为尽管这是一个微不足道的案例,但眼睛可以看到,这种类型的分析往往是非常重要的,而且实际上可以解决停机问题。因此,C#“保持简单”并要求您按照更容易适用和可解决的规则进行游戏。
关于c# - Lambda 分配局部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14224190/