在每次调用中重用幸存的局部变量。 UB?

时间:2016-12-28 11:49:16

标签: c# delegates anonymous-function undefined-behavior

我是C#的新手。我遇到了这样的代码示例:

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();
        }
    }
}

输出是:

Sum of 1 == 1
Sum of 2 == 4
Sum of 3 == 10
Sum of 4 == 20
Sum of 5 == 35

如您所见,调用之间的局部变量result未归零。这是“未定义的行为”吗?看起来它发生的原因是result的范围何时关闭,其生命周期未定义。

但是在C#中重用活动实体的规则是什么?它是规则 - “永远重用”,或者在某些情况下,何时会创建新的而不是重复使用旧的?

1 个答案:

答案 0 :(得分:3)

  

是“未定义的行为”吗?

不,这是明确定义的行为 - 而不是您期望的行为。

  

看起来是因为当结果范围关闭时,它的生命周期是未定义的。

不,result的生命周期超出了m()的范围。从C#5规范部分7.15.5.1:

  

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