harriyott.com

Tuesday, July 04, 2006

Using using

Daniel Moth has been experimenting with using the "using" statement to perform common entry and exit code. The using statement calls the constructor of a class at the beginning, and Dispose() at the end. The before code (status bar and wait cursor in his example) goes in the constructor, and the after code goes in Dispose(). Clever trick.

I post this because Daniel finishes his post thinking the approach is "wrong" and asking for feedback, but doesn't seem to have comments enabled. I'll post my thoughts here instead.

I think it's quite neat, and as the original developer, there's one less thing to think about when doing something, which is always useful. The problem comes with maintainability. He mentions the problem that no memory management actually takes place, and the leap would have to be made to understand that. This would only come to light when looking at the class.

If the maintenance coder didn't look at the class, just the using statement, she would assume that there was some memory stuff going on, and wonder where the heck the status bar text was getting changed. Eventually she'd have to look at the class, and realise that the original coder was a blatant liar. "Hey punk, there's no memory management here!". From that point on, she trusts the original coder a whole lot less, and has to check more classes just to confirm that they do what they say they do.

In this (admittedly contrived) example, a better approach would be to explicitly state what the code was doing by using meaningful method names:

SetGuiWaiting();
DoTheThing();
SetGuiReady();

or

guiController.SetWaiting();
DoTheThing();
guiController.SetReady();

Now the maintainer can just read what's going on without having to visit the other code. Not quite as pleasing for the original developer, but a lot easier to maintain. Still, an interesting idea, and it's always worth experimenting with things like this.

As for a class with only a constructor and a Dispose(), I'm not bothered by that, if the abstraction requires nothing else.

[Tags: ]

2 Comments:

Colin Angus Mackay said...

I think your comments about maintainability are quite valid. I used to do something similar in C++ by doing some funky stuff in an class' constructor and again in the destructor. That way, when an object was created on the stack it would run the destructor when it popped off the stack again when it went out of scope - regardless of how it went out of scope.

Both the C++ version I used to use and the C# version with the using(){} construct have the advantage that you don't have to put the clean up in a finally block in the event that an exception is thrown and the stack starts to unwind.

I also wrote about something similar here: http://blogs.wdevs.com/colinangusmackay/archive/2004/10/30/1010.aspx

July 04, 2006 5:05 PM  
Simon said...

I don't have so much of a problem with doing things in destructors - that's what they're there for. Dispose() is a special case, as it implies memory management, and the casual reader would assume that's all it did.

I tried reading your similar post, but your server said "Service Unavailable". I'll try later.

July 05, 2006 7:14 AM  

Post a Comment

Links to this post:

Create a Link

<< Home