The_Unknown_Member Ответов: 2

[C#] создание экземпляра объекта внутри блока работает также и вне блока ?


Привет. Мне интересно, как это работает:
using System;

namespace ConsoleApplication2
{
    class Program
    {
        public static void Main()
        {
            A kick = null;

            {
                kick = new A();
            } // End of the block 

            kick.HelloFromA(); // How I am able still to access it ? 
        }
    }

    class A
    {
        public void HelloFromA()
        {
            Console.WriteLine("Hello from A");
        }
    }
}


Разве коллектор gerbage не должен уничтожить объект A, на который указывает моя ссылочная переменная типа A ?

Что я уже пробовал:

Задавая вопрос здесь в CodeProject.com

PIEBALDconsult

Нет. Удар все еще находится в поле зрения.

2 Ответов

Рейтинг:
2

Peter Vegter

'kick' объявляется в блоке основного метода и включает в себя любые вложенные блоки. Итак, ваш код действителен. Наоборот, объявление во "внутреннем блоке" не известно в "внешнем блоке":

public static void Main()
{
    {
        A kick = null;
        kick = new A();
    }
 
    kick.HelloFromA(); // Here you can't access kick...
}

Сборщик мусора убирает удар после того, как он выходит "за рамки", но вы просто не знаете, когда (скорее всего, не сразу).


The_Unknown_Member

Это немного сбивает с толку. Как это вообще возможно ? Например, почему я не могу этого сделать:
публичный статический пустота главный()
{
int i;

for (int J = 0; J < 10; J++)
{
i = 10;
}

Приставка.WriteLine(i);
}


Пожалуйста, объясни мне все, парень. Спасибо!

Peter Vegter

Вы могли бы сделать это, за исключением того, что компилятор "думает", что я могу быть неназначенным, потому что цикл for может не выполняться (мы знаем это лучше, чем компилятор).Если вы используете: int i = 10; это нормально.

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

Может быть, взгляните на эти объяснения для большей ясности?:
http://www.ict.ru.ac.za/Resources/ThinkSharply/ThinkSharply/scope_and_lifetime.html
https://tutorialstown.com/csharp-variable-scopes/

The_Unknown_Member

Спасибо за ссылки! Я проверил их и узнал кое-что новое. Но он все равно не ответил на мой вопрос. Поскольку я плохо разбираюсь в объяснениях, я покажу вам новый фрагмент кода:

использование системы;

пространство имен ConsoleApplication2
{
программа занятий
{
публичный статический пустота главный()
{
int i; // объявление переменной i

{
i = 5; / / инициализация во внутреннем блоке
}
Приставка.WriteLine(i); / / и как здесь я могу вызвать его из внешнего блока ? Разве значение, присвоенное i, не доступно только во внутреннем блоке ?
}
}
}

Peter Vegter

Область видимости (где она "видна" и может быть использована) переменной определяется "пространством", в котором она объявлена. Назначение не изменяет исходную область действия переменной.

В вашем примере переменная i "видна" во всем методе Main (), включая любые содержащие ("внутренние") блоки, потому что она объявлена в самом внешнем блоке:

публичный статический пустота главный()
{
int i; / / декларация
{
i = 1; / / i также "виден" здесь
{
i = 2; / / i также "виден" здесь
{
i = 3; / / i также "виден" здесь
}
}
}
Приставка.WriteLine (i); / / печатает 3
}

Переменная i не "видна" во внешних блоках:

публичный статический пустота главный()
{
// внешний блок начинается здесь
{
int i; / / объявление во внутреннем блоке
{
i = 1; / / i также "виден" здесь
{
i = 2; / / i также "виден" здесь
{
i = 3; / / i также "виден" здесь
}
}
}
}
Приставка.WriteLine(i); / / i не 'виден' во внешнем блоке: ошибка
}

Рейтинг:
2

Dave Kreskowiak

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