Reputation: 50074
I was reading another answer. And it made me wonder, when do does one need to explicitly call Dispose if I am using using
statements?
EDIT:
Just to vindicate myself from being a total know-nothing, the reason I asked was because someone on another thread said something implying there was a good reason to have to call Dispose manually... So I figured, why not ask about it?
Upvotes: 4
Views: 1344
Reputation: 158061
You don't. The using
statement does it for you.
According to MSDN, this code example:
using (Font font1 = new Font("Arial", 10.0f))
{
byte charset = font1.GdiCharSet;
}
is expanded, when compiled, to the following code (note the extra curly braces to create the limited scope for the object):
{
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
}
Note: As @timvw mentioned, if you chain methods or use object initializers in the using statement itself and an exception is thrown, the object won't be disposed. Which makes sense if you look at what it will be expanded to. For example:
using(var cat = new Cat().AsDog())
{
// Pretend a cat is a dog
}
expands to
{
var cat = new Cat().AsDog(); // Throws
try
{
// Never reached
}
finally
{
if (cat != null)
((IDisposable)cat).Dispose();
}
}
AsDog
will obviously throw an exception, since a cat can never be as awesome as a dog. The cat will then never be disposed of. Of course, some people may argue that cats should never be disposed of, but that's another discussion...
Anyways, just make sure that what you do using( here )
is safe and you are good to go. (Obviously, if the constructor fails, the object won't be created to begin with, so no need to dispose).
Upvotes: 20
Reputation: 346
Be careful when using c# 3.0 object initializers though. An example can be found here: http://ayende.com/Blog/archive/2009/01/15/avoid-object-initializers-amp-the-using-statement.aspx
Upvotes: 10
Reputation: 8140
As far as i know
using (var myDisposable = new MyDisposable())
{
...
}
is basically translated by the compiler to
var myDisposable = new MyDisposable()
try
{
...
}
finally
{
myDisposable.Dispose();
}
Upvotes: 3
Reputation: 14391
Normally you don't. This is the point of the using statement. There is however a situation where you have to be careful:
If you reassign the variable to another value the using statement will only call the Dispose method on the original value.
using (someValue = new DisposableObject())
{
someValue = someOtherValue;
}
The compiler will even give you a Warning about this:
Possibly incorrect assignment to local 'someValue' which is the argument to a using or lock statement. The Dispose call or unlocking will happen on the original value of the local.
Upvotes: 12
Reputation: 24835
The whole point of the using statement is that if your object implements IDisposable, the dipose will be called at the end of the code block. That's what it's there for, to do it automaticaly for you.
Upvotes: 3
Reputation: 33474
Never. It will call Dispose once the statements inside using blocks finish execution.
Upvotes: 5