The scope of variable in inner anonymous method

2019-07-19 14:17发布

问题:

See the code

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

    }
}

OutPut

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

Link to Example

Normally the scope of variable outerValue would end after calling t.OuterMethod(). But in the case of using anonymous type, Console printed the output clearly (Console.WriteLine(outerValue)) which means the scope of variable didn't end. What do actually the compiler do to determine its scope? Will it assign the scope of Main method to the variables used inside the anonymous method? I know how to use but don't know how it works. Please guide me?

Edit

Suppose the anonymous method attached to an event. The event might be executing a lot later. Then the variable would be in memory. rite? If a lot of events assigned, a lot of memory!. Its a bad thing I suppose. Did I make any mistake?

回答1:

The scope of the variable (the region of program text within which it is possible to refer to it without qualification) remains the same.

The "lifetime" of the variable is effectively extended: the lambda expression captures the variable. The compiler will have generated a private nested class for you, with that variable in - both the method and the delegate refer to the same instance of this nested class, and that instance won't be eligible for garbage collection until the method no longer refers to it and the delegate instance is eligible for garbage collection.



回答2:

Anonymous methods are compiled into their own classes. These classes have fields for each of the captured variables. The instance of the class is 'the scope'.

What variables are captured? All top level symbols.

For example.

Action a = () => this.ANumber;

this is captured.

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

Only aNumber is captured.



标签: c# oop closures