Nick Strupat
Nick Strupat

Reputation: 5063

Is it reasonable to avoid explicit calls to Dispose()?

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

Answers (6)

Andrew Shepherd
Andrew Shepherd

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

Clafou
Clafou

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

Eric Lippert
Eric Lippert

Reputation: 660455

Is it reasonable to make a rule against explicitly calling Dispose() on an IDisposable object?

No.

Are there any cases where a using statement cannot properly ensure an IDisposable 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

Muath Ali
Muath Ali

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

Brian Rasmussen
Brian Rasmussen

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

JaredPar
JaredPar

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

Related Questions