2016-10-21 2 views
0

Во-первых, это не боян этого вопроса:Сделайте анонимные методы inline?

Are anonymous methods defined inline?

Я думаю, что спрашивающий задает другой вопрос.

Я спрашиваю о методе, в котором, когда во время процесса компиляции вызов метода заменяется фактическим методом.

Мое понимание анонимных методов заключается в том, что они фактически компилируются в конкретные методы с назначенным компилятором именем. Это делается для уменьшения накладных расходов на стек. Когда анонимные методы скомпилированы, они одинаковы?

+0

Любое количество бесплатных .NET-декомпиляторов .NET может показать вам ответ на этот вопрос. –

ответ

0

Анонимные методы работают точно так же, как обычные методы - если компилятор JIT решает встроить их, они могут быть встроены.

Однако, скорее всего, вы не вызываете анонимный метод напрямую - вы вызываете делегата, который указывает на анонимный метод. В этом случае, как и при любом другом делегировании делегата, компилятор не может встраивать что-либо, поскольку он не знает во время компиляции (или JIT-time), какой метод действительно будет вызываться.

Я думаю, вы путать с тем, как дженерики работают в .NET, а не анонимные методы в явном виде, особенно контрастируют с шаблонами С ++ - например, если я collection.Select(i => i.SomeProperty) в C#, есть еще только один метод Select [1]; как бы вы встроили метод i => i.SomeProperty, когда есть другие вызовы Select, которые принимают разные функции в качестве аргументов? Напротив, использование шаблонов в C++ позволяет встраивать аргументы «функции», поскольку шаблоны являются только функцией генерации кода во время компиляции; любое использование аналогичного шаблона Select в C++ даст вам отдельный фрагмент кода, при этом не задействован метод.

Излишне говорить, что это всего лишь деталь реализации. Для будущего компилятора было бы целесообразно встраивать вызов метода, делая вид, что он не является делегатом и не встраивает сам метод Select.

[1] - Технически во время JIT-компиляции может быть несколько версий метода Select для аргументов другого типа - это не имеет никакого отношения к этому сценарию; он по-прежнему не делает другого метода для всех возможных аргументов.

+0

Во время компиляции JIT существует * несколько версий метода 'Select', поэтому (в общем случае) я не понимаю, почему компилятор JIT сможет встроить (конкретный) общий метод. Тем не менее, LINQ - довольно частный случай, так как есть много сантехники, которое происходит с 'IEnumerable ', и, кроме того, оно лениво оценено, поэтому я сомневаюсь, что любой из методов расширения, таких как 'Select', будет наложен на практике. Единственная ситуация, о которой я могу думать, - это немедленный «ToList», то есть «items.Select (i => i.x) .ToList()», полностью встроенный в цикл. – Groo

+0

(во всяком случае, моя точка зрения заключается в том, что 'Select' и другие методы LINQ особенно сложны для inline) – Groo

+0

@Groo Согласовано, вложение фактических методов расширения LINQ было бы трудным, если не невозможным. Тем не менее, мой вопрос касается вложения анонимного делегата. Если он не встроен, вызов .Select() добавит два вызова в стек, тогда как будет только один, если анонимное тело делегата будет включено. – oscilatingcretin

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