tags:

views:

108

answers:

4

Assuming I have a method in my command architecture pattern that alters the contents of graphics path like so: (GraphicsPath is IDisposable)

(this is purely an untested, quick example)

public void DoSomething(ref GraphicsPath path) 
{
   if(path != null) 
      {
      List<PointF> pts = new List<PointF>();
      foreach(PointF pt in path.PathPoints) 
      {
         //again, just a silly example.
         float y = pt.X;
         float x = pt.Y;
         pts.Add(new PointF(x, y));
      }
   path.Dispose(); //<-- Do I need this?
   path = new GraphicsPath(pts.ToArray(), path.PathTypes);
  }
}

Do I need to dispose the path before setting the path equal to the new path? If so, why?

A: 

Yeah, you probably should.

If the object is disposable, that's basically saying that it has some resources that need to be cleaned up (like maybe a file open or a database or something).

Calling dispose, cleans those up (in an ideal world)

McKay
A: 

Without discussing the merit of your function, yes - you need to call Dispose so that the object can clean itself up of resources it allocated along the way.

Another reason - at the point you assign anything to it, you are taking responsibility for its lifetime, so you need to make sure whatever it was using before gets cleaned up.

Otávio Décio
+8  A: 

Yes. Since you're passing the path variable by reference you "orphan" the previous instance when you reassign it. Cleaning up with Dispose() is the right thing to do.

Paul Sasik
+1, I'd add that path should be in a `using block`, minus the assignment.
sixlettervariables
@sixlettervariables: But it can't be in a `using` block, because the `path` variable passed both in and out as a `ref` argument. This is why several comments above are advocating for a different method signature instead.
Daniel Pryden
IMHO the answer is not as simple as this. You're assuming the calling code won't need the reference anymore. This isn't certain. However, ultimately I regard the design of the function as flawed.
AdamRalph
Furthermore, I think the best answer is to drop the ref parameter and return the new object instead, without calling any Dispose() methods at all. That way the consuming code can manage the lifetimes of the objects as it sees fit.
AdamRalph
@AdamRalph: i completely agree with you. i've always been a fan of using return values over ref params. My answer is simple and simply limited to the scope of the question. A refactoring would definitely be helpful here.
Paul Sasik
Fair enough - but I still think the answer is not so simple. In the context of this code you cannot be certain that calling Dispose() is the right thing to do.
AdamRalph
AdamRalph... as I state above, this is a Command Pattern. Meaning that I'm creating *dozens* of command objects, and executing them on multiple GraphicsPath objects... if I were to implement it your way, I would have to call a command, dispose, call a command, dispose, call a command, dispose. It would create some really terrible looking code and, to be honest a larger margin for error on the part of other coders.
blesh
That's really a comment on the disposable idiom itself, rather than this isolated code example.
AdamRalph
+4  A: 

This is a difficult question to answer. If the consuming code should be responsible for managing the lifetime of the object, then it should call Dispose(), instead of your code. The reason for this is that the consuming code could be maintaining another reference to the instance, besides the one it has passed to your code, and it may expect to be able to continue using this reference after your method has been called.

Or, if the semantics of your class indicate that it will manage the lifetime of the object once it has been passed, then it should call Dispose() as you've described.

As a general note, whenever an object implements IDisposable, you should always explictly call it's Dipose() method when you have finished with it (or use the reference within a using block).

Having said the above, you may want to revisit your design as the semantics it represents are not intuitive.

AdamRalph