2013-12-11 2 views
2

Смотрите кодОбъем переменной внутренней анонимного метода

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.WriteLine(outerValue)), что означает, что область действия переменной не заканчивается. Что действительно делает компилятор, чтобы определить его область действия? Будет ли он присваивать область применения метода Main переменным, используемым внутри анонимного метода? Я знаю, как использовать, но не знаю, как это работает. Пожалуйста, направляйте меня?

Редактировать

Пусть анонимный метод, прикрепленный к событию. Событие может быть , выполняющее много позже. Тогда переменная будет в памяти. обряд? Если много назначенных событий, много памяти !. Я думаю, что это плохо. Произошла ли ошибка?

+0

Переменная скомпилирована в закрытие анонимного метода для использования и сохранения. –

+0

@AdamHouldsworth, затем объем закрытия? –

+0

См. Ответ Jon Skeet :-) –

ответ

5

Объем переменной (область текста программы, в которой можно ссылаться на нее без квалификации) остается неизменной.

«Срок службы» переменной эффективно расширяется: выражение лямбда захватывает переменную. Компилятор создаст для вас частный вложенный класс, причем эта переменная включена - как метод, так и делегат относятся к тому же экземпляру этого вложенного класса, и этот экземпляр не будет иметь права на сбор мусора до тех пор, пока метод больше не будет ссылаться к нему, и экземпляр делегата имеет право на сбор мусора.

+0

Предположим, что анонимный метод прикреплен к событию. Событие может быть выполнено намного позже. Тогда переменная будет в памяти. обряд? Если много событий назначено, много памяти !. Я думаю, что это плохо. Я допустил ошибку? –

+0

ответьте на этот вопрос тоже. –

+0

@SubinJacob: Во-первых, пожалуйста, дайте людям возможность обратиться к комментариям, прежде чем подталкивать их дальше. Stack Overflow не является вашим личным пулом слуг. У нас есть другие дела, связанные с нашей жизнью.Но да, это может быть поводом для беспокойства, но, по-видимому, вы только захватываете переменные, потому что вы * нуждаетесь в них, что означает, что это неотъемлемая проблема в том, что вы пытаетесь сделать, а не в реализации C#. (Там * * проблема в реализации C#, если несколько анонимных функций захватывают разные переменные из одной и той же области, но это намного сложнее.) –

2

Анонимные методы скомпилированы в свои классы. Эти классы имеют поля для каждой из захваченных переменных. Экземпляр класса - это «область действия».

Какие переменные захватываются? Все верхний уровень символы.

Например.

Action a =() => this.ANumber; 

this снят.

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

Только aNumber снят.

+3

Ну * иногда * создается новый класс. Не всегда, хотя это зависит от наличия каких-либо переменных. Когда только «это» захвачено, я считаю, что компилятор просто создает метод экземпляра для анонимной функции. –

+0

@JonSkeet Делает смысл. Спасибо за знание - всегда приятно получать ваш вклад. – Gusdor

+0

Предположим, что анонимный метод привязан к событию. Событие может быть выполнено намного позже. Тогда переменная будет в памяти. обряд? Если много событий назначено, много памяти !. Я думаю, что это плохо. Я допустил ошибку? –

Смежные вопросы