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

Неявная и явная типизация с именем С# 6

Одна из самых полезных функций С# 6 - nameof, которая позволяет программисту эффективно исключить использование магические строки.

В документации, nameof возвращает строку:

Используется для получения простого (неквалифицированного) имени строки для переменной, типа или члена.

Это работает отлично с явным вводом текста в следующем примере кода:

string magicString = nameof(magicString);

Однако при использовании неявной типизации с ключевым словом var:

var magicString = nameof(magicString);

компилятор выдает ошибку:

Нельзя использовать локальную переменную magicString до ее объявления

Затем я немного экспериментировал с С# Interactive, доступным в Visual Studio. Опять же, первый пример работал отлично, но на втором примере на этот раз была сделана другая ошибка:

error CS7019: Тип "magicString" не может быть выведен, поскольку его инициализатор прямо или косвенно ссылается на определение.

Выражение nameof явно возвращает строку, поэтому почему компилятор неявно вводит его при использовании с инициализированной переменной?

4b9b3361

Ответ 1

Языковая команда почувствовала, что это не стоит сложной спецификации.

Вы можете увидеть обсуждение здесь.

Основная причина такого поведения заключается в том, что spec говорит (§8.5.1) имена, объявленные с помощью var, не отображаются в заявлении объявления, так как до nameof не было способа, которым это могло бы быть действительный.

Неявно введенные локальные объявления переменных подчиняются следующим ограничениям:

  • ...
  • Инициализатор не может ссылаться на объявленную переменную

Без var утверждения, подобные int x = x = 1; или int x = 1, y = x;, являются законными; с var, ничего в этой форме не будет.

Ответ 2

Возможность объявлять переменную и назначать ее в одном и том же выражении является синтаксическим сахаром. Например, когда вы это говорите:

string magicString = nameof(magicString);

что вы на самом деле говорите:

string magicString;
magicString = nameof(magicString);

Поскольку magicString уже объявлен, вы можете использовать его в следующем логическом выражении как часть оператора naemof. Это связано с тем, что magicString теперь входит в область , которая видима для последующих операторов.

Теперь приведенное выше не выполняется, когда вы используете var, потому что все, что использует var для выполнения задания, действительно является частью всего одного заявления, а не синтаксического сахара для двух операторов, подобных приведенному выше примеру. Переменная magicString фактически не объявляется до тех пор, пока не будет вызвана функция/оператор/назначение функции, поэтому переменная не является частью области, пока она не выполнила назначение, то есть в следующем утверждении (ы).

SLaks ссылался на оригинальное обсуждение этой проблемы, но в отмечены примечания из этого более позднего дизайна С# собрание команды об этой проблеме по вопросу "Должен ли var x = nameof (x) работать?":

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

Другими словами, это не относится к nameof.