Компилятор превращает локальную функцию SetI
в отдельный метод уровня класса.Поскольку этот отдельный метод уровня класса не является конструктором, вам не разрешено присваивать ему поля только для чтения.
Таким образом, компилятор принимает это:
public class A
{
private readonly int i;
public A()
{
void SetI()
{
i = 10;
}
SetI();
}
}
и превращает его в этот:
public class A
{
private readonly int i;
public A()
{
<.ctor>g__SetI|1_0();
}
[CompilerGenerated]
private void <.ctor>g__SetI|1_0()
{
i = 10;
}
}
( SharpLab . Я остановил readonly
, чтобы он скомпилировался.)
Как видите, он пытается присвоить i
из метода <.ctor>g__SetI|1_0()
, который не является конструктором.
К сожалению, спецификация языка C # 7.0 еще не была опубликована, поэтому я не могу процитировать ее.
Точно так жепроисходит, если вы пытаетесь использовать делегата:
public class A
{
private readonly int i;
public A()
{
Action setI = () => i = 10;
setI();
}
}
Получает скомпилированный в:
public class A
{
private readonly int i;
public A()
{
Action action = <.ctor>b__1_0;
action();
}
[CompilerGenerated]
private void <.ctor>b__1_0()
{
i = 10;
}
}
( SharpLab , снова без readonly
.)
... который также не компилируется.