Sunday, October 31, 2010

.NET ConditionalAttribute

The preface to this blog post is found here Windows Forms .NET handling unhandled exceptions. The short story being that I have a smart client / winforms application running on the clients machine in release mode. All unhandled exceptions caught are reported to a sharepoint list. However in debug mode on the developer machine we do not want to handle unhandled exceptions since this can be useful when debugging in Visual Studio.

Hence we need to differentiate between debug and release mode.

This have traditionally been done using the compiler directives as here below

The Form1_Load event handler method is only here used to set the correct title on the form so it is easy to see if you are in debug or release mode. It uses the IsAssemblyDebugBuild helper method for this.

The 2 only methods that are really relevant to the ConditionalAttribute class is the button1_Click event handler method and the Log() method.

You can see from the screenshots here below what happens when you run the application in debug / release mode and click the button.

This is more or less to be expected after all we only want the logging to happen when in debug mode.

So what is going on behind the scenes, lets have a look at the MSIL code for the Log() in debug and then release mode.

If we look at this MSIL code we can see that it is the calling function that is modified not the Log() method. Since the code is JIT'ed the extra Log() method does not incur a performance overhead in release mode since the JIT compiler looks ahead and only JITs methods that will be called.

This is a contrived example however it is not unusual for conditional code to become rather complex over the time of a project. And this code is actually introducing a fatal flaw in release mode which is not present in debug mode.

Ideally the code base should be the same in debug and release mode, and conditional compiler directives is in IMHO a bad idea when we have the ConditionalAttribute.