Что избавляется, когда используется ключевое слово «using» - PullRequest
3 голосов
/ 05 марта 2010

Давайте рассмотрим пример:

using (var someObject = new SomeObject())
{
    var someOtherObject = new SomeOtherObject();
    someOtherObject.someMethod(); 
}

SomeOtherObject также реализует IDisposable. Будет ли SomeOtherObject утилизироваться при утилизации SomeObject? Что будет с SomeOtherObject? (удаление SomeOtherObject не реализовано в методе Dispose SomeObject)

Ответы [ 8 ]

11 голосов
/ 05 марта 2010

Нет. Будут удалены только поля в предложении using. В вашем случае только someObject.

В основном этот код переводится в

var someObject = null;
try
{
  someObject = new SomeObject()

  var someOtherObject = new SomeOtherObject();
  someOtherObject.someMethod(); 
}
finally
{
  if (someObject != null )
  someObject.Dispose()
}
5 голосов
/ 05 марта 2010

Никакой другой объект не будет утилизирован.

Ваш код будет транслироваться примерно так:

var someObject = new SomeObject();
try
{
   var someOtherObject = new SomeOtherObject();
   someOtherObject.someMethod(); 
}
finally
{
    ((IDisposable)someObject).Dispose();
}

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

5 голосов
/ 05 марта 2010

Нет, SomeOtherObject будет не будет удален

Ваш код реструктурируется компилятором следующим образом:

var someObject = new SomeObject();
try
{
    var someOtherObject = new SomeOtherObject();
    someOtherObject.someMethod(); 
}
finally
{
    if (someObject != null)
        someObject.Dispose();
}
1 голос
/ 05 марта 2010

Вы должны написать это так:

using (var someObject = new SomeObject()) {
    using (var someOtherObject = new SomeOtherObject()) {
        someOtherObject.someMethod(); 
    }
}

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

1 голос
/ 05 марта 2010

someOtherObject будет обычно собираться сборщиком мусора. Если вы не предоставили соответствующий финализатор (деструктор), который вызывает Dispose(), он никогда не будет вызван. Только someObject.Dispose() будет вызываться, когда поток выполнения покидает блок using.

1 голос
/ 05 марта 2010

цитата из MSDN напрямую:

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

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

0 голосов
/ 05 марта 2010

Не уверен, что это то, откуда вы пришли; someOtherObject не будет доступен вне блока using; из-за правил определения объема .

using (Stream stream = File.OpenRead(@"c:\test.txt"))
{
   var v1 = "Hello"; //object declared here, wont be accessible outside the block
   stream.Write(ASCIIEncoding.ASCII.GetBytes("This is a test"), 0, 1024);
} //end of scope of stream object; as well as end of scope of v1 object.

v1 = "World!"; //Error, the object is out of scope!

Ошибка компилятора: «Имя v1 не существует в текущем контексте.»

Даже после этого произойдет ошибка.

    {
        int x=10;
    }

    x = 20; //Compiler error: "The name x does not exist in the current context."

См. это и это для получения дополнительной помощи.

0 голосов
/ 05 марта 2010

Метод Dispose объекта, на который ссылается someObject, будет вызван, когда элемент управления выйдет из блока using.Вы можете SuppressFinalize в методе Dispose, и в этом случае система не будет вызывать finalizer этого объекта (в противном случае это произойдет).
Объект, на который ссылается someOtherObject, будет, однако, собран GC в соответствующее время, посколькукогда элемент управления покидает блок, на него не будет ссылаться ни один объект, и он будет помечен для сбора.

...