参见代码
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
方法的范围分配给匿名方法中使用的变量吗?我知道如何使用,但不知道它是如何工作的。请指导我?
修改
假设附加到事件的匿名方法。事件可能是 之后执行了很多。然后变量将在内存中。仪式?如果 分配了很多事件,记忆力很大!我想这是件坏事。 我犯了什么错误吗?
答案 0 :(得分:5)
变量的范围(程序文本的区域可以无限制地引用它)保持不变。
变量的“生命周期”有效地扩展:lambda表达式捕获变量。编译器将为您生成一个私有嵌套类,其中包含该变量 - 方法和委托都引用此嵌套类的相同实例,并且该方法不再适用于垃圾收集,直到该方法不再引用它和委托实例有资格进行垃圾收集。
答案 1 :(得分:2)
匿名方法被编译到自己的类中。这些类具有每个捕获变量的字段。该类的实例是“范围”。
捕获了哪些变量?所有顶级符号。
例如。
Action a = () => this.ANumber;
this
被捕获。
int aNumber = this.ANumber;
Action a = () => aNumber;
仅捕获aNumber
。