The compiler turns the SetI
local function into a separate class-level method. Since this separate class-level method is not a constructor, you are not allowed to assign to readonly fields from it.
So the compiler takes this:
public class A
{
private readonly int i;
public A()
{
void SetI()
{
i = 10;
}
SetI();
}
}
and turns it into this:
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. I left off the readonly
so it would compile.)
As you can see, it's trying to assign i
from the method <.ctor>g__SetI|1_0()
, which isn't a constructor.
Unfortunately the C# 7.0 language specification hasn't yet been published, so I can't quote it.
Exactly the same happens if you try and use a delegate:
public class A
{
private readonly int i;
public A()
{
Action setI = () => i = 10;
setI();
}
}
Gets compiled to:
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, again without the readonly
.)
... which likewise fails to compile.