Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which is better, and when: using statement or calling Dispose() on an IDisposable in C#?

Suppose I have the following:

using(var ctx = DataContextFactory.Create(0))
{ ... Some code ... }

Why not just do the following and lose a couple of curly braces?:

var ctx = DataContextFactory.Create(0);
ctx.Dispose();

Thanks for the advice!

like image 721
mkelley33 Avatar asked Jun 23 '09 19:06

mkelley33


People also ask

When Dispose is called in IDisposable?

Rule#1: Properly dispose of classes that implement IDisposable. The first rule is whenever you are consuming a class that implements the IDisposable interface; you should call the “Dispose” method when you are done with that class.

What happens if you dont Dispose IDisposable?

IDisposable is usually used when a class has some expensive or unmanaged resources allocated which need to be released after their usage. Not disposing an object can lead to memory leaks.

What will happen if we call Dispose () method directly?

The Dispose() methodThe Dispose method performs all object cleanup, so the garbage collector no longer needs to call the objects' Object. Finalize override. Therefore, the call to the SuppressFinalize method prevents the garbage collector from running the finalizer. If the type has no finalizer, the call to GC.

Will the Dispose () of IDisposable be called when GC runs in case the instance is not created within using block?

Answer: None. Calling Dispose can release unmanaged resources, it CANNOT reclaim managed memory, only the GC can do that.


4 Answers

The first is better. It ensures it is disposed even if an exception is thrown, and it correctly handles the case where Create(0) returns null (i.e. it doesn't attempt to call Dispose() on a null instance).

like image 81
Marc Gravell Avatar answered Oct 20 '22 01:10

Marc Gravell


A using statement is always better because...

  • you can't forget to call Dispose(), even as the code evolves into different code paths
  • Dispose() gets called even if there's an exception. It also checks for null before calling Dispose(), which may be useful (assuming you're not just calling new).

One non-obvious (to me, anyway) trick with using is how you can avoid excessive nesting when you have multiple disposable objects:

using (var input = new InputFile(inputName))
using (var output = new OutputFile(outputName))
{
    input.copyTo(output);
}

The VS code formatter will leave the two statements starting in the same column.


In fact, in some situations you don't even have to repeat the using statement...

using (InputFile input1 = new InputFile(inputName1), input2 = new InputFile(inputName2))

However, the restrictions for declaring multiple variables on the same line applies here so the types must be the same and you cannot use the implicit type var.

like image 29
Trevor Robinson Avatar answered Oct 20 '22 01:10

Trevor Robinson


Where you can, use using for the reasons Marc cites. OTOH this isn't a brain dead solution as sometimes the lifetime of the object can't be defined as a lexical scope so use it reasonably.

like image 40
BCS Avatar answered Oct 20 '22 01:10

BCS


The only place you don't want to use a using block is where the disposable object is scoped outside of the function. In this case, your class should implement IDisposable and dispose of the object in its Dispose().

like image 21
Jon B Avatar answered Oct 20 '22 01:10

Jon B