Установить только для чтения поля в конструкторе локальной функции c # - PullRequest
14 голосов
/ 15 марта 2019

Следующее не компилируется.

public class A
{
    private readonly int i;

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

        SetI();
    }
}

Сбой с этой ошибкой:

CS0191 Невозможно назначить поле только для чтения (кроме как в конструкторе или инициализаторе переменной)

Технически мы все еще не в конструкторе, поскольку видимость локальной функции ограничена, поэтому мне интересно, почему это не компилируется.

1 Ответ

22 голосов
/ 15 марта 2019

Компилятор превращает локальную функцию 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.)

... который также не компилируется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...