1

匿名方法是内联定义的吗?在下面的示例中,委托对象“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();
}
4

2 回答 2

6

匿名方法是内联定义的吗?

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

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

不,xFun方法中定义。Del不是方法,它是委托类型。

“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();
}
于 2013-06-14T14:56:29.013 回答
1

这称为闭包x一旦执行委托,它就会捕获并使用它。它是通过一些编译器魔法完成的。

不过,有时可能会令人困惑。例如,如果您x在定义委托后进行更改,则将使用该更改值。

于 2013-06-14T13:55:10.020 回答