Sunday, March 04, 2007

Save Your Fingers - Let Your Snippets Do The Typing

Snippets are a really cool tool for creating commonly used code blocks or structures that can't be re-used through class libraries/sub-procedures etc. because the definition or layout is similar but not the content of the code. Generally snippets can save you a whole lot of typing. If you are not familiar with Visual Studio 2005 snippets, we suggest you Google them for more information.

I've created some snippets for code I commonly write and posted them in zip file that can be downloaded from Yortsoft website.

These snippets include;
  • dispobj - Expands to create a class definition for an object that correctly implements the dispoable pattern, including the IDisposable interface, suppression of finalisation if disposed prior to the finaliser being called by the GC, use of isDisposing in a common private method to allow only non-managed resources to be disposed when called from the finaliser and an IsDisposed property.
  • propctlapp - Creates an 'appearance property' for use in a (user or custom) control class. This property comes with XML documentation, the category attribute applied with a setting of 'Appearance', the set accessor contains an if condition for checking to see if the value actually changed before calling the Invalidate method (and any other user code you insert), the description attribute (value set by snippet variable) and the browesable attribute set to true.
  • eventdec - Declares an event using the generic EventHandler delegate and creates a protected virtual OnEventName for raising the event. Also includes XML documentation for the event and method created.
  • invokeself - Creates a method, for use within a form or control class, which invokes itself if this.InvokeRequired is true, or executes the required code if this.InvokeRequired is false.
  • memberregions - Creates the following 'regions' in the current code module; Fields, Events, Constructors/Destructors, Public Methods, Public Properties, Overrides, Private Methods, Event Handlers. This is really a personal preference I have for formatting my own code, but I've seen other people on the 'Net doing the same so I thought someone else might like this snippet too.
  • propc - Creates a property with both get and set accessors, with an if (oldvalue != value) condition in the set accessor. Also includes XML documentation for the property created.

I'll add more snippets as I think of them. Let me know what you think of these ones, or if you have an improvement to suggest.

Friday, March 02, 2007

Exceptions You Should Always Break On

One of the great features for debugging in Visual Studio 2005 is the exceptions dialog. This can be accessed from the debug -> exceptions menu. If you don't have this menu item (some default settings picked during installation don't include this option) then you might need to 'customise' your tools bars to add it.

The exceptions dialog allows you to specify how the debugger should behave when an exception is thrown. The most common thing to do here is to specify 'always break on xxx' where xxx is a type or category of exceptions. This is similar to the VB6 'Break On All Errors' option, except that you can specify specific exception types to break on instead of all or nothing. Note : If you want the equivalent of VB6's 'Break On All Errors' option, simply tick the check box next to Common Language Runtime Exceptions.

I regularly use this feature when debugging, as often I know an error is occurring somewhere in the code when I perform a particular action, but one of my event handlers, or my global error handling is preventing me from finding the specific location. By saying to break on all errors, or the specific error I'm dealing with, Visual Studio will stop and break into the code, highlight the line that threw the error, as each error occurs. This lets me quickly and easily locate the source of the problem.

This had lead me to some new thinking on exceptions. I am coming to believe there are some exceptions that should never, ever occur. Of course, we all make mistakes, so that is to say there are some exceptions that should only occur when there is truly a bug.

So far I have only applied this thinking to one exception type (although it may apply to others) - System.NullReferenceException.

System.NullReferenceException is the same as the old VB6 'Object reference not set' error. It basically means you tried to use a property or method on a variable that has not been assigned an object value. Now let's think about the times this might happen;

  1. You simply didn't foresee this variable ever being null (shame on you), and this is a bug. In this case, fix your code so it checks whether the variable is null or not. If it is, and that should be exception, see point 4.
  2. Someone passed you a null argument and you don't accept nulls - in which case you should check the argument before using it and throw the System.ArgumentNullException if it is null. Don't forget to provide the name of the argument.
  3. You're using an object you think might be null sometimes, and if you get the null reference exception you catch it and do something else. BAD BAD BAD - throwing exceptions is bad for performance, and unnecessary try/catch blocks look ugly. Instead, use an if to check if the value is null and do one thing, else do the other.
  4. You're using an object that shouldn't be null, but if it is the problem should throw an exception. Cool, fine, great... but don't throw System.NullReferenceException - it doesn't tell you anything ! Instead, throw a more meaningful exception, even if it means creating one yourself. Say you've attempted to find a plug-in object by name in a collection of loaded plug-ins and the result is a null reference, and that should be an error condition. How about creating and throwing a ConfigurationException instead ? At least this way you, the user, their administrator or their support agent has a better chance of figuring out the problem is a missing plug-in if the error occurs in a deployed system. Also, and possibly more importantly, code calling yours can catch ConfigurationException and confidently handle it if necessary, where as catching System.NullReferenceException is kind of ambiguous - did you get it because the add-in reference was null, or some other variable in the same routine ?

If you take this approach then you can permanently check the 'break on thrown' checkbox for System.NullReferenceException. What does this do for you ? It ensures that if you're debugging the exception occurs you will always know where it happened, and you will always know that it's a problem you need to fix. It also ensures you and your colleagues don't write sloppy code that throws too many exceptions (and catches them) causing poor performance.

So, what do you think ? Should System.NullReferenceException be banned from deliberate or expected exception lists ? Are there any other exception types you think belong here ? Let me know !