2009-02-13 3 views
4

Я читал еще один ответ. И это заставило меня задуматься, когда нужно ли явно вызывать Dispose, если я использую операторы using?Когда вам нужно позвонить IDisposable, если вы используете `using` заявления?

EDIT:

Просто оправдает себя от не быть общей ноу-ничего, поэтому я спросил потому, что кто-то в другом потоке сказал что-то подразумевающее была хорошая причина, чтобы вызвать Dispose вручную ... Так Я подумал, почему бы не спросить об этом?

+0

Мне нравятся такие, казалось бы, простые вопросы о StackOverflow. Я всегда удивляюсь, сколько информации вы можете получить из такого вопроса. Я не знал о проблеме инициализаторов объектов ... –

+0

SO - это, безусловно, удивительный веб-сайт. Мне нравится здесь. –

ответ

20

У вас нет. Заявление using делает это за вас.


Согласно MSDN, этот пример кода:

using (Font font1 = new Font("Arial", 10.0f)) 
{ 
    byte charset = font1.GdiCharSet; 
} 

расширяется, при компиляции, в следующем коде (обратите внимание на дополнительные фигурные скобки, чтобы создать ограниченную область применения для объекта):

{ 
    Font font1 = new Font("Arial", 10.0f); 
    try 
    { 
    byte charset = font1.GdiCharSet; 
    } 
    finally 
    { 
    if (font1 != null) 
     ((IDisposable)font1).Dispose(); 
    } 
} 

Примечание: Как @timvw mentioned, если вы цепляете методы или используете инициализаторы объектов в самой инструкции using и генерируете исключение, объект не будет удален. Это имеет смысл, если вы посмотрите, к чему он будет расширен. Например:

using(var cat = new Cat().AsDog()) 
{ 
    // Pretend a cat is a dog 
} 

расширяется

{ 
    var cat = new Cat().AsDog(); // Throws 
    try 
    { 
    // Never reached 
    } 
    finally 
    { 
    if (cat != null) 
     ((IDisposable)cat).Dispose(); 
    } 
}  

AsDog будет, очевидно, бросить исключение, так как кошка никогда не может быть столь же удивительным, как собака. Кошка никогда не будет удалена. Конечно, некоторые люди могут утверждать, что кошек никогда не нужно удалять, но это еще одна дискуссия ...

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

+1

+1. , , Я не кошка. , , –

+0

Как здорово, что в рекламе, которую я читал, есть бигль, ищущий работу на Careers.stackexchange.com –

5

Никогда. Он выведет Dispose после того, как выполняются операторы внутри использования блоков.

3

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

12

Обычно вы этого не делаете. Это точка используемого оператора. Однако есть ситуация, когда вы должны быть осторожны:

Если вы переназначите переменную на другое значение, оператор using вызовет только метод Dispose на исходное значение.

using (someValue = new DisposableObject()) 
{ 
    someValue = someOtherValue; 
} 

Компилятор даже дать вам Предупреждение об этом:

Возможно неправильное назначение в местный «SomeValue», который является аргументом в использовании или блокировки заявления. Вызов Dispose или разблокировка произойдет по первоначальному значению локального.

+0

+1 для упоминания проблемы переназначения. –

+1

Я считаю, что это предупреждение заменено на ошибку в C# 3.5: «ошибка CS1656: не может назначить« someValue », потому что это« использование переменной »» – Dathan

3

Насколько я знаю

using (var myDisposable = new MyDisposable()) 
{ 
    ... 
} 

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

var myDisposable = new MyDisposable() 
try 
{ 
    ... 
} 
finally 
{ 
    myDisposable.Dispose(); 
} 
+1

Он также охватывает весь блок в фигурных скобках, чтобы ограничить область myDisposable и добавляет проверку в блоке finally только для выполнения Dispose() для непустых экземпляров myDisposable. – Dathan

Смежные вопросы