Сохраняет ли оператор using ссылку на объект (ы), которые он получает? - PullRequest
2 голосов
/ 04 июня 2019

При использовании выражения «using», например:

  using (Global.Instance.BusyLifeTrackerStack.GetNewLifeTracker())
  {
    ...

вместо

  using (var lt = Global.Instance.BusyLifeTrackerStack.GetNewLifeTracker())
  {
    ...

Оператор «using» сохранит ссылку на возвращенный объект, чтобы обеспечить егоне будет ли мусор собираться слишком много раньше? ... либо, если для него не объявлена ​​явная переменная (первый пример кода)?

Второй пример кода явно подходит, но первый ???

Будем благодарны за любую документацию и / или ссылку на информацию.

Ответы [ 3 ]

3 голосов
/ 04 июня 2019

Да, реальная ссылка сохраняется, так что в конце может быть вызван метод Dispose. Этот шаблон часто используется для выполнения своего рода «побочного эффекта» при утилизации, когда вам явно не требуется доступ к одноразовому объекту внутри блока using. Например, в Razor using(Html.BeginForm){...} разрешает утилизацию возвращенного объекта для вывода тега </form> в конце.

Тривиальным примером в C # будет:

public class MessageGenerator : IDisposable
{
    public MessageGenerator()
    {
        Console.WriteLine("To whom it may concern,");
    }

    public void Dispose()
    {
        Console.WriteLine("Thanks and goodbye.");
    }
}

И использование как это:

using (new MessageGenerator())
{
    Console.WriteLine("Please give me lots of reputation.");
}

выдаст вывод примерно так:

К кому это может относиться,

Пожалуйста, дайте мне много репутации

Спасибо и до свидания.

1 голос
/ 04 июня 2019

Вот пример того, что компилятор делает за кулисами. Код ниже:

using (File.OpenRead("Test.txt")){}

... преобразуется в:

FileStream fileStream = File.OpenRead("Test.txt");
try
{
}
finally
{
    if (fileStream != null)
    {
        ((IDisposable)fileStream).Dispose();
    }
}

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

1 голос
/ 04 июня 2019

Чтобы ответить на документацию и справочную часть вашего вопроса:

Документация для оператора using примечания:

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

Что касается синтаксиса первого кодового блока, стандарт C # имеет следующее для синтаксиса:

using_statement
    : 'using' '(' resource_acquisition ')' embedded_statement
    ;

resource_acquisition
    : local_variable_declaration
    | expression
    ;

Там вы заметите, что resource_acquisition может быть объявлением локальной переменной или выражением, которое использует ваш первый блок кода.

...