Подтвердить что ты не робот

Почему поля класса не могут быть переменными?

class A
{
    A()
    {
        var x = 5;   // this is allowed
    }

    var _x = 5;   // the compiler is unhappy
}

Я думаю, что компилятор должен иметь возможность выводить тип для переменной-члена так же, как и для локального. Итак, какая разница?

4b9b3361

Ответ 1

Эрик Липперт ответил на ваш вопрос прямо здесь: Почему нет var в полях?

В принципе, для общего случая потребуется перезаписать компилятор С#, поскольку способ, которым он в настоящее время выполняет вывод типа, не будет работать для циклов присваиваний переменных var.

Ответ 2

Ключевое слово var было создано для анонимных типов, которые могут использоваться только внутри метода.

Кроме того, вы ошибаетесь; компилятор не всегда может вывести поле var.

Что произойдет, если вы скомпилируете следующее:

class A {
    public readonly var value = B.value;
}

class B {
    public readonly var value = B.value;
}

Эту ситуацию невозможно воссоздать с локальными переменными, так как переменная не может быть указана до ее определения.

Общая проблема заключается в том, что вы просите компилятор использовать информацию о типе, пока он все еще генерирует эту информацию.
Эрик Липперт объясняет более подробно.

Ответ 3

Я вижу две причины:

  • Возможно, было бы желательно сделать декларацию типов в открытом явном интерфейсе
  • Трудно реализовать. Компилятор С# компилируется в несколько этапов.
    Сначала он разбирает все, кроме органов тела, так что он знает обо всем вне функциональных тел. Затем он может использовать эту информацию для компиляции тел метода индивидуально. То, что происходит при компиляции одного метода, не оказывает большого влияния на то, что происходит при компиляции других тел метода.
    Если вы можете использовать var для полей, тело выражения инициализатора поля повлияет на тип поля и, следовательно, на многие другие методы. Таким образом, он не соответствует дизайну компилятора.

Ответ 5

Это предположение, но инициализация полей уровня класса должна выполняться как часть процесса инициализации (конструктора) для типа, тогда как инициализация переменной уровня метода происходит, когда создается кадр стека метода. Возможно, это различие связано с тем, как эти процессы компилируются (как их реализация создается) внутри рамки.