匿名方法是否内联定义?

时间:2013-06-14 13:51:22

标签: c# .net delegates scope anonymous-function

匿名方法是否内联定义?在下面的示例中,委托对象“d”引用了匿名方法,该方法访问Fun方法中定义的“x”变量。 “x”的范围应限于Fun方法,但是当我们调用MyFun时,它会调用作为参数传递的委托并增加“x”的值。

输出结果是“6”,这是怎么发生的?在匿名方法中,“x”的值或首先是“x”变量本身的值是多少?

public delegate void Del();

public void Fun()
{
    int x = 5;
    Del d = delegate { x++;  };
    MyFun(d);
    Console.WriteLine(x);
}

public static void MyFun(Del d)
{
    d();
}

2 个答案:

答案 0 :(得分:6)

  

匿名方法是否内联定义?

我不知道“内联”是什么意思。

  

在下面的示例中,委托对象“d”引用了匿名方法,该方法访问在Del方法中定义的“x”变量。

不,x方法中定义了FunDel不是方法,而是委托类型。

  

“x”的范围应限于Fun方法。

正确。回想一下,“x的范围”被定义为“程序文本的区域,其中x可以通过其非限定名称查找”。您正确使用该术语; Fun的正文是x的范围。请注意,匿名方法位于Fun内,因此x在范围内。

  

当我们调用MyFun时,它会调用作为参数传递的委托并递增“x”的值。

正确。

  

输出结果为“6”。

正确。

  

这是怎么发生的?

问题并不完全清楚。听起来你已经提供了如何发生这种情况的解释:变量x在匿名函数内的范围内,函数递增变量,因此变量的值会发生变化。

如果您的问题是“编译器为了实现这一目标而生成了什么代码?”编译器假装你写了类似的东西:

public delegate void Del();

private class Locals
{
    public int x;
    public void AnonymousMethod() { x++; }
}    

public void Fun()
{
    Locals locals = new Locals();
    locals.x = 5;
    Del d = locals.AnonymousMethod;
    MyFun(d);
    Console.WriteLine(locals.x);
}

public static void MyFun(Del d)
{
    d();
}

答案 1 :(得分:1)

这称为Closure。它捕获x并在委托执行后立即使用它。它是通过一些编译魔术完成的。

但是,有时可能会让人感到困惑。例如,如果在定义委托后更改x,则将使用该更改值。