Вложенные блоки кода и области видимости переменных

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

Данное руководство взято с сайта foxdevelop.com. При перепубликации обязательно указывайте источник.

В теле метода можно вкладывать другие блоки кода.

class Program
{
    static void Main()
    {
        int age = 19;
        {
            int one = 23;
        }
    }
}
Code language: C# (cs)

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

class Program
{
    static void Main()
    {
        int age = 19;
        {
            int one = 23;
            {
                int two = 45;
                {
                    int three = 56;
                }
            }
        }
    }
}Code language: C# (cs)

Важно помнить: инструкция int xxxx = xxx; перед вложенным дочерним блоком является параллельной по отношению к этому блоку.

Например, строка int age = 19; и расположенный под ней вложенный блок кода — это две независимые инструкции. Не принимайте эту конструкцию за тело метода целиком.


Жизненный цикл

Рассмотрим пример

    static void Main()
    {
        int a = 10;
        {
            int b = 20;
        }
    }Code language: C# (cs)

В данном примере присутствуют две локальные переменные. Внешняя переменная a относится к внешней области видимости функции Main, а переменная b принадлежит внутреннему вложенному блоку.

Проследим выполнение по шагам и посмотрим, как распределяется память стека.

Шаг 1: Выполняется только int a = 10;. В стеке выделяется память под переменную a со значением 10;

Шаг 2: Переходим во внутренний блок и выполняем int b = 20;. В стек добавляется переменная b. Порядок сверху вниз: b, a;

Шаг 3: Внутренний блок кода завершает работу. Переменная b выгружается из стека, в стеке остаётся только a.

Шаг 4: Метод Main завершает выполнение. Переменная a также удаляется из стека, все переменные программы уничтожаются, работа программы прекращается.

Итог

Переменная, объявленная внутри вложенного блока, начинает свой жизненный цикл с момента объявления и существует до завершения выполнения содержащего её блока.

После завершения работы вложенного блока все локальные переменные из него выгружаются из стека и уничтожаются.

Само тело метода по сути является одним большим блоком кода.


Область видимости

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

Посмотрите пример

    static void Main()
    {
        int a = 10;
        {
            int a = 20;
        }
    }Code language: C# (cs)

В примере выше переменная a во внутреннем вложенном блоке имеет то же имя, что и внешняя переменная a. Это вызовет ошибку, компиляция не пройдёт.

Причина: область видимости int a = 10; охватывает все фигурные скобки, внутри которых находится эта строка. В этой области запрещено использовать переменные с повторяющимися именами. Несмотря на то что запись int a = 20; находится во вложенном блоке, этот блок входит в тело метода, где уже объявлена переменная a. Компилятор обнаружит повтор имени и отметит строку волнистой красной линией.

Ограничение сохраняется даже если для второй переменной a выбрать другой тип данных.

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

Как видно на изображении, область видимости внешней переменной a выделена жёлтым цветом, а внутренней — зелёным. Очевидно, внешняя область полностью охватывает внутреннюю, из-за чего и возникает конфликт имён.

Решение простое: достаточно переименовать внутреннюю переменную a.

Рассмотрим ещё один пример

Возникнет ли конфликт при такой записи кода?

class Program
{
    static void Main()
    {
        int a = 10;

        {
            double b = 20;
        }

        {
            double b = 30;
        }

    }
}Code language: C# (cs)

Ответ: нет. Хотя существуют две переменные с именем b, их области видимости не пересекаются, поэтому компиляция завершится успешно. Первая переменная b действует только в своём блоке, вторая — в отдельном блоке. Смотрите иллюстрацию.

Цветом на рисунке отмечены области видимости каждой переменной b. Надеюсь, теперь читателям всё стало понятно.

Вложенные блоки кода и области видимости переменных

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *