C# 在每次调用中重用幸存的局部变量。乌兰巴托?

C# 在每次调用中重用幸存的局部变量。乌兰巴托?,c#,delegates,anonymous-function,undefined-behavior,C#,Delegates,Anonymous Function,Undefined Behavior,我是新来的。我遇到了这样的代码示例: namespace App1 { delegate int Sum(int number); class TestAnonymusMethod { static Sum m() { int result = 0; // is not zeroed between calls Sum del = delegate (int number)

我是新来的。我遇到了这样的代码示例:

namespace App1
{
    delegate int Sum(int number);

    class TestAnonymusMethod
    {
        static Sum m()
        {
            int result = 0;  // is not zeroed between calls

            Sum del = delegate (int number)
            {
                for (int i = 0;  i <= number;  i++)
                    result += i;
                return result;
            };
            return del;
        }

        static void Main()
        {
            Sum del1 = m();

            for (int i = 1;  i <= 5;  i++)
                Console.WriteLine("Sum of {0} == {1}", i, del1(i));

            Console.ReadKey();
        }
    }
}
如您所见,局部变量
result
在调用之间不归零。这是“未定义的行为”吗?看起来这是因为当
result
的作用域关闭时,其生命周期未定义

但是在C#中重用活动实体的规则是什么?是“始终重用”的规则,还是在某些情况下,会创建新的而不是重用旧的

这是“未定义的行为”吗

不,这是定义明确的行为——只是不是你期望的行为

看起来这是因为当结果的范围关闭时,它的生存时间是未定义的

否,
result
的生存期已超出
m()
的范围。根据C#5规范第7.15.5.1节:

当外部变量被匿名函数引用时,外部变量被称为已被匿名函数捕获。通常,局部变量的生存期仅限于与其关联的块或语句的执行(§5.1.7)。但是,捕获的外部变量的生存期至少会延长到从匿名函数创建的委托或表达式树符合垃圾收集条件为止

这是“未定义的行为”吗

不,这是定义明确的行为——只是不是你期望的行为

看起来这是因为当结果的范围关闭时,它的生存时间是未定义的

否,
result
的生存期已超出
m()
的范围。根据C#5规范第7.15.5.1节:

当外部变量被匿名函数引用时,外部变量被称为已被匿名函数捕获。通常,局部变量的生存期仅限于与其关联的块或语句的执行(§5.1.7)。但是,捕获的外部变量的生存期至少会延长到从匿名函数创建的委托或表达式树符合垃圾收集条件为止


为什么它应该归零?您只调用了一次“m()”方法,所以它只被初始化为0一次。@Evk,我已经重命名了这个问题。由于
result
不是
static
,所以对我来说有点奇怪(在C++之后)-在每次调用中重用相同的变量(及其当前值)。为什么要将其归零?您只调用了一次“m()”方法,所以它只被初始化为0一次。@Evk,我已经重命名了这个问题。由于
result
不是
static
,所以对我来说有点奇怪(在C++之后)-在每次调用中重用相同的变量(及其当前值)。谢谢!但是我是否理解了7.15.5.1的正确性?:
结果将被保证至少在
del1
的作用域关闭之前处于活动状态?@user1234567:否,直到委托可用于垃圾收集
del1
是一个局部变量,恰好引用了委托。您可以将该值传递给保留对同一委托的引用并使其保持活动状态的其他对象。基本上,委托具有它所需的所有状态,包括
result
变量。您需要考虑对象和垃圾收集,而不是变量和范围。谢谢!但是我是否理解了7.15.5.1的正确性?:
结果将被保证至少在
del1
的作用域关闭之前处于活动状态?@user1234567:否,直到委托可用于垃圾收集
del1
是一个局部变量,恰好引用了委托。您可以将该值传递给保留对同一委托的引用并使其保持活动状态的其他对象。基本上,委托具有它所需的所有状态,包括
result
变量。您需要考虑对象和垃圾收集,而不是变量和范围。
Sum of 1 == 1
Sum of 2 == 4
Sum of 3 == 10
Sum of 4 == 20
Sum of 5 == 35