Объявления переменных следующим образом, если отчетность


на другом форуме возникла проблема, и я знал, как ее исправить, но она выявила особенность компилятора, свойственную мне. Человек получал ошибку "встроенный оператор не может быть объявлением или помеченным оператором", потому что у них было объявление переменной после оператора if без скобок. Это не было их намерением, но они прокомментировали строку кода сразу после оператора if, который сделал объявление переменной фактической строкой кода для выполнять. Во всяком случае, это предыстория, которая подводит меня к этому.

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

if (true)
    int i = 7;

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

if (true)
{
    int i = 7;
}

ни один из фрагментов кода не является полезным. Тем не менее, второй в порядке. В чем конкретно заключается объяснение такого поведения?

4 58

4 ответа:

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

  • с надписью-заявлением - Я думаю, что это за старомодный goto сообщении
  • декларация-заявление - что было бы объявлением переменной
  • embedded-statement - который включает в себя практически все остальные заявления

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

Если ( логическое выражение)embedded-statement
если ( логическое выражение)embedded-statement еще embedded-statement

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

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

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

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

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

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

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

Пример Кода

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

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

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

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);
    }