内部匿名方法中变量的范围

时间:2013-12-11 11:19:06

标签: c# oop closures

参见代码

public class Test
{
    public static void Main()
    {
        Test t = new Test();
        var AnonymousMethod = t.OuterMethod();
        AnonymousMethod("passedValue");
    }
     public delegate void SampleDelegate(string InputText);

     public SampleDelegate OuterMethod()
    {
        string outerValue="outerValue";
        return (x => {
            Console.WriteLine(x);
            Console.WriteLine(outerValue);
        });

    }
}

输出

Success  time: 0.02 memory: 33816 signal:0
passedValue
outerValue

链接到Example

通常,变量outerValue的范围将在调用t.OuterMethod()后结束。但是在使用匿名类型的情况下,Console清楚地打印输出(Console.WriteLine(outerValue)),这意味着变量的范围没有结束。编译器实际上做了什么来确定其范围?它会将Main方法的范围分配给匿名方法中使用的变量吗?我知道如何使用,但不知道它是如何工作的。请指导我?

修改

  

假设附加到事件的匿名方法。事件可能是   之后执行了很多。然后变量将在内存中。仪式?如果   分配了很多事件,记忆力很大!我想这是件坏事。   我犯了什么错误吗?

2 个答案:

答案 0 :(得分:5)

变量的范围(程序文本的区域可以无限制地引用它)保持不变。

变量的“生命周期”有效地扩展:lambda表达式捕获变量。编译器将为您生成一个私有嵌套类,其中包含该变量 - 方法和委托都引用此嵌套类的相同实例,并且该方法不再适用于垃圾收集,直到该方法不再引用它和委托实例有资格进行垃圾收集。

答案 1 :(得分:2)

匿名方法被编译到自己的类中。这些类具有每个捕获变量的字段。该类的实例是“范围”。

捕获了哪些变量?所有顶级符号。

例如。

Action a = () => this.ANumber;

this被捕获。

int aNumber = this.ANumber;
Action a = () => aNumber;

仅捕获aNumber