Будет ли Dispose () вызываться в операторе using с нулевым объектом?

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?

Паоло Тедеско
источник
1
Связанный stackoverflow.com/questions/2513035
Брайан Расмуссен

Ответы:

172

Да, Dispose()вызывается только для ненулевых объектов:

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

reko_t
источник
30
Обратите внимание, что даже если ваша переменная равна нулю, блок using выполняется, и если вы ссылаетесь на свою переменную внутри блока using без предварительной проверки на нуль, вы получите NullReferenceException. Во избежание неправильной интерпретации в этом ответе должно быть указано: «Да, Dispose()вызывается только для ненулевых объектов».
Сурфен
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

Вы не получите исключение нулевой ссылки согласно моему опыту. Это будет просто проигнорировано.

малайский
источник