Wednesday, July 21, 2010

Old school folks who have done Fortran, C, C++ etc knows the old friend, #if. Net introduced a [Conditional] attribute and give examples for use. On occasion I have seen newer developers voicing a dislike of seeing #if in code and advocate the use of [Conditional] as a standard. This does not fly for me – simply because it results in code becoming twisted.

Often the reason for the resistance is simply unfamiliarity with it, or in some cases, some past experience working with horrible usage (I reviewed the code base from a major (not-Microsoft) software provider of tax software and saw nightmare usage patterns with the #if) has left a conditioning on their psyche.

For example, the following code WILL NOT COMPILE

Code Snippet

publicvoid Init(HttpApplication context)

{

context.EndRequest += EndRoutine;

}

[Conditional("TRACE")]

privatevoid EndRoutine(object o, EventArgs e)

{

Error 1 Cannot create delegate with 'ErrorTracking.EndRoutine(object, System.EventArgs)' because it has a Conditional attribute

This variation will compile.

Code Snippet

publicvoid Init(HttpApplication context)

{

#if TRACE

context.EndRequest += EndRoutine;

#endif

}

privatevoid EndRoutine(object o, EventArgs e)

{

It is possible to still use the conditional by chaining routines – but I dislike it severely because it add an extra call and complicate code reviews (i.e. I believe in KISS)

Code Snippet

publicvoid Init(HttpApplication context)

{

context.EndRequest += EndRoutine;

}

privatevoid EndRoutine(object o, EventArgs e)

{

EndRoutine2(o, e);

}

[Conditional("TRACE")]

privatevoid EndRoutine2(object o, EventArgs e)

{

Another use of conditional compile results in code being modified. Since the Conditional Attribute does not allow items to be returned NOR the use of out parameters, you are forced to use properties or the instance or instance methods. Both of these approaches end up obtuficating the code.

Example of error when using out

Code Snippet

[Conditional("TRACE")]

privatevoid EndRoutine2(object o, EventArgs e, outstring x)

Error 1 Conditional member ErrorTracking.EndRoutine2(object, System.EventArgs, out string)' cannot have an out parameter.

The use of #if and similar cannot be avoided by the use of the [Conditional] attribute. The [Conditional] attribute is ideal for tracing and logging, but for a lot of other uses – it fails.