Объявления переменных после операторов if

Проблема возникла на другом форуме, и я знал, как ее исправить, но она показала особенность компилятора, свойственного мне. У человека возникла ошибка: «Встроенный оператор не может быть объявлением или помеченной инструкцией», потому что у них было объявление переменной, следующей за оператором if без скобок. Это не было их целью, но они прокомментировали строку кода, непосредственно следуя за оператором if, что сделало объявление переменной фактической строкой кода для выполнения. Во всяком случае, это тот фон, который подводит меня к этому.

Следующий код является незаконным

if (true) int i = 7; 

Однако, если вы заключите это в скобки, это все законно.

 if (true) { int i = 7; } 

Ни одна часть кода не полезна. Но второй – в порядке. Что конкретно объясняет такое поведение?

Спецификация языка C # различает три типа операторов (подробнее см. Главу 8). В общем, вы можете иметь следующие утверждения:

  • labeled-statement – я предполагаю, что это для старомодного goto
  • statement-statement – это объявление переменной
  • embedded-statement – который включает почти все остальные утверждения

В выражении if тело должно быть встроенным-заявлением , что объясняет, почему первая версия кода не работает. Вот синтаксис if из спецификации (раздел 8.7.1):

if ( boolean-expression ) embedded-statement
if ( boolean-expression ) embedded-statement else embedded-statement

Объявление переменной – заявление-заявление , поэтому оно не может появляться в теле. Если вы заключите объявление в скобки, вы получите блок-оператор, который является встроенным-заявлением (и поэтому он может появиться в этой позиции).

Когда вы не включаете скобки, она выполняет следующую строку, как если бы она была окружена скобками. Так как не имеет смысла объявлять переменную в этой строке (вы никогда не сможете ее использовать), компилятор C # не позволит этому предотвратить случайное выполнение этого действия, не зная (что может привести к тонким ошибкам ).

Вот часть Эрика Липперта должна сказать о компиляторе C # на этом SO ответ на разрешение имен:

… C # – это не «гадать, что означает пользователь», язык … компилятор по дизайну жалуется громко, если лучший матч – это то, что не работает

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

Второй случай вызывается непосредственно в спецификации языка C # в начале раздела 8.0

Пример приводит к ошибке времени компиляции, потому что для оператора if требуется встроенный оператор, а не оператор для ветви if. Если бы этот код был разрешен, тогда переменная i была бы объявлена, но никогда не использовалась. Обратите внимание, однако, что, помещая объявление i в блок, пример действителен.

Пример кода

 void F(bool b) { if (b) int i = 44; } 

Добавление закрывающих и открывающих фигурных скобок в другой части, если помогло мне, как я сделал ниже, в отличие от того, что я делал, прежде чем добавлять их;

До: это вызвало ошибку:

 protected void btnAdd_Click(object sender, EventArgs e) { if (btnAdd.Text == "ADD") { CATEGORY cat = new CATEGORY { NAME = tbxCategory.Text.Trim(), TOTALSALEVALUE = tbxSaleValue.Text.Trim(), PROFIT = tbxProfit.Text.Trim() }; dm.AddCategory(cat, tbxCategory.Text.Trim()); } else // missing brackets - this was causing the error var c = getCategory(); c.NAME = tbxCategory.Text.Trim(); c.TOTALSALEVALUE = tbxSaleValue.Text.Trim(); c.PROFIT = tbxProfit.Text.Trim(); dm.UpdateCategory(c); btnSearchCat_Click(btnSearchCat, e); } 

После: добавлены скобки в ветке else

 protected void btnAdd_Click(object sender, EventArgs e) { if (btnAdd.Text == "ADD") { CATEGORY cat = new CATEGORY { NAME = tbxCategory.Text.Trim(), TOTALSALEVALUE = tbxSaleValue.Text.Trim(), PROFIT = tbxProfit.Text.Trim() }; dm.AddCategory(cat, tbxCategory.Text.Trim()); } else { var c = getCategory(); c.NAME = tbxCategory.Text.Trim(); c.TOTALSALEVALUE = tbxSaleValue.Text.Trim(); c.PROFIT = tbxProfit.Text.Trim(); dm.UpdateCategory(c); } btnSearchCat_Click(btnSearchCat, e); } 
  • В Java, используя оператор switch с диапазоном значений в каждом случае?
  • Что лучше ? Несколько операторов if, или один, если с несколькими условиями
  • Есть ли разница в удалении фигурных фигурных скобок из операторов If в java
  • Почему проверка равноценности одной переменной по многим значениям всегда возвращает true?
  • inline условные выражения в angular.js
  • Ошибка компилятора при объявлении переменной внутри условия if и фигурных скобок
  • Как избежать цепей «если»?
  • Я получил «приложение схемы не процедуру» в последнем рекурсивном вызове функции
  • if (cin >> x) - Почему вы можете использовать это условие?
  • Точка с запятой в конце выражения «if»
  • Могу ли я использовать if (указатель) вместо if (pointer! = NULL)?
  • Давайте будем гением компьютера.