Чи буде викликано Dispose () у використовуваному операторі з нульовим об'єктом?


179

Чи безпечно використовувати usingоператор на (потенційно) нульовому об'єкті?
Розглянемо наступний приклад:

class Test {
    IDisposable GetObject(string name) {
        // returns null if not found
    }

    void DoSomething() {
        using (IDisposable x = GetObject("invalid name")) {
            if (x != null) {
                 // etc...
            }
        }
    }
}

Чи гарантовано, що Disposeбуде викликано лише якщо об'єкт недійсний, і я не отримаю NullReferenceException?


Відповіді:


172

Так, Dispose()викликається лише для ненульових об'єктів:

http://msdn.microsoft.com/en-us/library/yh598w02.aspx


30
Зауважте, що навіть якщо ваша змінна є null, використовуючий блок виконується, і якщо ви посилаєтесь на свою змінну всередині використовуючого блоку без попередньої перевірки нуля, ви отримаєте NullReferenceException. Щоб запобігти неправильному тлумаченню, у цій відповіді повинно бути зазначено: "Так, Dispose()викликається лише на ненульових об'єктах".
surfen

37

Розширення usingперевіряє, чи немає об'єкта nullперед тим, як викликати Disposeйого, так що так, це безпечно.

У вашому випадку ви отримаєте щось на кшталт:

IDisposable x = GetObject("invalid name");
try
{
    // etc...
}
finally
{
    if(x != null)
    {
        x.Dispose();
    }
}

14

У вас повинно бути все в порядку:

using ((IDisposable)null) { }

Тут не виняток.

Побічна примітка: не помиліться цим foreachі IEnumerableде буде викинуто виняток.


1

Так, перед розпорядженням посилання буде перевірено на нуль. Ви можете перевірити себе, переглянувши свій код у Reflector.


-3

Ви не отримаєте нульового довідкового винятку відповідно до мого досвіду. Це буде просто проігноровано.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.