Is it safe to use the using
statement on a (potentially) null object?
Consider the following example:
class Test {
IDisposable GetObject(string name) {
// returns null if not found
}
void DoSomething() {
using (IDisposable x = GetObject("invalid name")) {
if (x != null) {
// etc...
}
}
}
}
Is it guaranteed that Dispose
will be called only if the object is not null, and I will not get a NullReferenceException
?
6 Answers 6
Yes, Dispose()
is only called on non-null objects:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/using
3 Comments
Dispose()
is only called on non-null objects".The expansion for using
checks that the object is not null
before calling Dispose
on it, so yes, it's safe.
In your case you would get something like:
IDisposable x = GetObject("invalid name");
try
{
// etc...
}
finally
{
if(x != null)
{
x.Dispose();
}
}
Comments
You should be ok with it:
using ((IDisposable)null) { }
No exception thrown here.
Side note: don't mistake this with foreach
and IEnumerable
where an exception will be thrown.
Comments
Yes, before Disposing the reference will be null-checked. You can examine yourself by viewing your code in Reflector.
Comments
I came across this question as I had an object where I don't know whether it requires and supports disposing. The way I dealt with this is to cast it to IDisposable
using the as
keyword. Here's an example:
void DoSomethingWithMyType(Func<IMyType> factory)
{
IMyType myObj = factory();
// Some but not all implementations IMyType of implement IDisposable
using (myObj as IDisposable)
{
myObject.DoSomething();
}
}
In my example scenario IMyType
is an interface that doesn't implement IDisposable
itself, but some classes that implement IMyType
are known to implement IDisposable
while others do not. In the former case, the myObj as IDisposable
expression produces an IDisposable
object on which on implicit call to Dispose
is made leaving the using
block. In the latter case, the expression produces null
, in which case nothing happens, and crucially, no exception is raised when leaving the using
block.
Comments
You will not get null reference exception as per my experience. It will be simply ignored.
If a null resource is acquired, then no call to Dispose is made, and no exception is thrown.