Set readonly fields in a constructor local function c#

2k Views Asked by At

The following does not compile.

public class A
{
    private readonly int i;

    public A()
    {
        void SetI()
        {
            i = 10; 
        }

        SetI();
    }
}

It fails with this error:

CS0191 A readonly field cannot be assigned to (except in a constructor or a variable initializer)

Technically are we not in the constructor still, since the visibility of the local function is limited, so I'm wondering why this does not compile.

1

There are 1 best solutions below

1
On BEST ANSWER

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.