2015-01-14 2 views
0

мне интересно понять, что происходит за кулисами, в такой ситуации:Накладные определения делегата внутри другого метода

public static void OuterMethod() { 
    // some random code 
    var a = 42; 
    var b = "meaning of life";   

    Func<string, object> factory = (aString) { 
     // do something with a and b 
     return "Hello World"; 
    }; 

    // some more random code 
    factory("My string"); 
} 

Я особенно заинтересован в тех случаях, когда OuterMethod называют очень часто. В моем случае это конвейер запросов MVC, где OuterMethod вызывается один раз для каждого запроса.

Могу ли я причинить много накладных расходов, имея необходимость строить factory каждый раз, когда вызывается метод? Я мог бы легко перенести Func вне OuterMethod в свой собственный статический метод, однако в моем фактическом сценарии, потому что он определен внутри, у меня есть доступ к множеству переменных, которые мне нужно сделать для моих вычислений, которые в противном случае мне нужно было бы включить в подпись метод, определенный снаружи. Возможно, это всего лишь микро-оптимизация, но я хотел бы лучше понять, как компилятор относится к этим заявлениям.

+1

Правильный ответ Servy, вы будете создавать новую ссылку на делегата для каждого вызова OuterMethod. Однако с точки зрения дизайна это, вероятно, нарушит принцип единой ответственности. OuterMethod отвечает за создание объектов (или выполнение вычисления) и любую реальную работу OuterMethod. Поэтому предпочтителен выбор фабрики/расчета по своему методу. Конечно, если вы используете OuterMethod только для создания среды состояния для делегата, тогда все в порядке. –

ответ

2

Фактическая лямбда приведет к созданию нового именованного метода (вы просто не знаете, что это имя), созданного во время компиляции (точная семантика будет зависеть от некоторых особенностей).

Единственная работа, выполняемая при каждом вызове метода, заключается в создании нового объекта-делегата, который имеет свой собственный указатель на один и тот же метод. Если построить этот экземпляр одного объекта действительно слишком много для вас (подсказка: его нет), то вы можете сохранить эту работу, извлекая делегат из метода.

+0

Спасибо! Всегда цените свое понимание. У меня было ощущение, что меня позаботятся в какой-то момент во время компиляции, но просто хочу быть уверенным :) –

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