Почему компилятор С# 7 превращает локальные функции в методы в том же классе, где их родительская функция. В то время как для Анонимных методов (и Лямбда-выражений) компилятор генерирует вложенный класс для каждой родительской функции, которая будет содержать все его Анонимные методы как методы экземпляра?
Например, код С# (анонимный метод):
internal class AnonymousMethod_Example
{
public void MyFunc(string[] args)
{
var x = 5;
Action act = delegate ()
{
Console.WriteLine(x);
};
act();
}
}
Создает IL-код (анонимный метод), похожий на:
.class private auto ansi beforefieldinit AnonymousMethod_Example
{
.class nested private auto ansi sealed beforefieldinit '<>c__DisplayClass0_0'
{
.field public int32 x
.method assembly hidebysig instance void '<MyFunc>b__0' () cil managed
{
...
AnonymousMethod_Example/'<>c__DisplayClass0_0'::x
call void [mscorlib]System.Console::WriteLine(int32)
...
}
...
}
...
Пока это, код С# (локальная функция):
internal class LocalFunction_Example
{
public void MyFunc(string[] args)
{
var x = 5;
void DoIt()
{
Console.WriteLine(x);
};
DoIt();
}
}
Создает IL-код (локальная функция), похожий на:
.class private auto ansi beforefieldinit LocalFunction_Example
{
.class nested private auto ansi sealed beforefieldinit '<>c__DisplayClass0_0' extends [mscorlib]System.ValueType
{
.field public int32 x
}
.method public hidebysig instance void MyFunc(string[] args) cil managed
{
...
ldc.i4.5
stfld int32 LocalFunction_Example/'<>c__DisplayClass1_0'::x
...
call void LocalFunction_Example::'<MyFunc>g__DoIt1_0'(valuetype LocalFunction_Example/'<>c__DisplayClass1_0'&)
}
.method assembly hidebysig static void '<MyFunc>g__DoIt0_0'(valuetype LocalFunction_Example/'<>c__DisplayClass0_0'& '') cil managed
{
...
LocalFunction_Example/'<>c__DisplayClass0_0'::x
call void [mscorlib]System.Console::WriteLine(int32)
...
}
}
Обратите внимание, что функция DoIt
превратилась в статическую функцию в том же классе, что и ее родительская функция.
Также закрытая переменная x
превратилась в поле во вложенном struct
(не вложенном class
как в примере Анонимного метода).