gpt4 book ai didi

c# - Lambda 分配局部变量

转载 作者:可可西里 更新时间:2023-11-01 14:56:02 26 4
gpt4 key购买 nike

考虑以下来源:

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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com