Reputation: 5063
Is it reasonable to make a rule against explicitly calling Dispose()
on an IDisposable
object?
Are there any cases where a using
statement cannot properly ensure an IDisposable
object is cleaned up?
Upvotes: 9
Views: 2772
Reputation: 45272
One natural assumption is that you can always call Dispose
on an object, and this will clean up the object's resources, regardless of what state the object is in.
This natural assumption is not always a correct assumption.
An example is with WCF client proxies..
The correct way to manage proxy lifetime is as follows:
var serviceClient = new sandbox.SandboxServiceClient();
serviceClient.HelloWorld(name);
if(serviceClient.State == CommunicationState.Faulted)
{
serviceClient.Abort();
}
else
{
serviceClient.Dispose();
}
Switching to the using
syntax will result in unsafe code:
using (var serviceClient = new sandbox.SandboxServiceClient())
{
serviceClient.HelloWorld(name);
} // Here An exception will be thrown if the channel has faulted
You could argue (as we all do) that this is a flawed design aspect of WCF, but the reality of programming is that we sometimes have to modify our style to accommodate the frameworks we're using. Here's an example where a blanket rule against explicit Dispose
cannot apply, even when the lifetime of the object is contained within one function call.
Upvotes: 3
Reputation: 15410
A using
statement (which really is shorthand for a try/finally with Dispose
called in the finally block) is for scenarios where you acquire a resource, make use of it, then dispose of it within one same method. If you don't have such a linear usage of the resource (e.g. its usage is split across methods) you will have to call Dispose
.
Upvotes: 2
Reputation: 660455
Is it reasonable to make a rule against explicitly calling
Dispose()
on anIDisposable
object?
No.
Are there any cases where a
using
statement cannot properly ensure anIDisposable
object is cleaned up?
There are certainly cases where it makes no sense to use using
to dispose an object for you. For example, all cases where the desired lifetime of the object is not bound by a particular activation of a method containing a using
statement.
Consider for example a disposable object which "takes over management" of another disposable object. The "outer" object may well be disposed by a using
block, but how is the "inner" object, likely stored in a private field of the outer object, to be disposed without an explicit call to Dispose()
?
Upvotes: 11
Reputation: 186
I would vote against such rule, what if you have an object you want to use multiple times across several function calls, a using statement will force the disposal of that object, the next time you want to use it, you have to re-initialize...
Upvotes: 1
Reputation: 116471
If the cost of creating instances of a disposable type is high (e.g. a type which encapsulates a remote connection), you may want to reuse instances to amortize the cost. In that case using
will not be useful and you'll have to call Dispose
at some point.
Upvotes: 1
Reputation: 755347
In some cases it's simply not possible to avoid an explicit call to Dispose
and still maintain proper semantics. For example consider IDisposable
objects which have a field also of type IDisposable
. They must us an explicit call to Dispose
to dispose the field
class Container : IDisposable {
private readonly IDisposable _field;
public void Dipose() {
// Don't want a using here.
_field.Dispose();
}
}
Upvotes: 5