TIP: Conditional code execution with the ConditionalAttribute and the #IF ... #ENDIF Preprocessor Directive

by brunofig 25. September 2008 17:51

While developing an application, you need to execute some code only when a defined condition is meet, for example, you have a product and you want to have specific code execution for both a release version and a trial version. You could change the code and compile different code for each version, or you could use one (or both) of the following solutions:

  • The ConditionalAttribute indicates that a method is callable if a specified preprocessing identifier is applied to the method.
  • The #IF ... #ENDIF Preprocessor Directive conditionally includes source code at compile-time if a specified preprocessing identifier is defined.

The ConditionalAttribute class

An practical example of the usage of this attribute is the framework itself. The System.Diagnostics.Debug class uses in its methods this attribute so that when you are debugging your assembly, the debugging information is output:

image

 

Let build a simple example:

using System;
using System.Collections.Generic;
using System.Diagnostics;

public class MyConditionalSample
{
    public static void Main()
    {
        Debug.WriteLine("Some debug info!");
        ExecuteIfRelease();
        ExecuteIfDebug();
    }
    
    [Conditional("RELEASE")]
    private static void ExecuteIfRelease()
    {
        Console.WriteLine("Hello world! I'm a release assembly!");
    }
    
    [Conditional("DEBUG")]
    private static void ExecuteIfDebug()
    {
        Console.WriteLine("Hello world! I'm a debug assembly!");
    }
        
}

This is a straight forward example. In the Main method we call the Debug.WriteLine method to output some debug info, and call both ExecuteIfRelease and ExecuteIfDebug methods.

Looking at these methods, notice that they have the Conditional attribute with the conditional compilation symbols RELEASE and DEBUG.

So, on our command line we will first simple compile and execute our code:

image

As you can see, no output was wrote, this because no conditional symbols were defined in our compilation. Let's change our compilation command to include the RELEASE symbol:

image

Now that we added the RELEASE symbol, the runtime now executes our ExecuteIfRelease method.

Changing the symbol to DEBUG will now make the runtime execute the ExecuteIfDebug method and also output our debug message, that we can trace in the DebugView:

image

image

If we look at our compile code in the .NET Reflector we will see that both methods are declared on the code but only the ExecuteIfDebug method is declared on the Main method:

image

#IF ... #ENDIF Preprocessor Directive

The #IF...#ENDIF preprocessor takes this to another level. When using this directive, you are telling the compiler to include/exclude code from the compiled assembly.

So, taking our example and changing it to use instead this directive:

using System;
using System.Collections.Generic;
using System.Diagnostics;

public class MyConditionalSample
{
    public static void Main()
    {
        Debug.WriteLine("Some debug info!");
        #if(RELEASE)
        ExecuteIfRelease();
        #elif(DEBUG)
        ExecuteIfDebug();
        #endif
    }
    
    #if(RELEASE)
    private static void ExecuteIfRelease()
    {
        Console.WriteLine("Hello world! I'm a release assembly!");
    }
    #elif(DEBUG)
    private static void ExecuteIfDebug()
    {
        Console.WriteLine("Hello world! I'm a debug assembly!");
    }
    #endif
        
}

Now let's compile and execute our code using the DEBUG symbol:

image

The code executed has expected, with no visible difference from the prior sample. So what's the catch?

The catch, has told, is in the compiled code itself:

image

Notice that our compiled code doesn't include the ExecuteIfRelease method.

Conclusion

So there you have it. To simple ways of call conditional code. One more thing: although we used the command line compiler to define de conditional symbols, the same can be made using Visual Studio. Simply go to the project's properties, and on the Build tab set your custom compilations symbols, or use the DEBUG and/or TRACE symbols:

image

I would like to say thanks to my good friend Paulo for pointing me into the right direction on this matter.

kick it on DotNetKicks.com

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

C# | Tips&Tricks

Powered by BlogEngine.NET 1.4.5.7
Theme by Mads Kristensen

About the author

Hi!

My name is Bruno and I'am a senior consultant. When I'm not working, you can catch me playing with my daugther, taking photos and hanging out with my wife and friends. :)

You can also check my dark side or have fun with my vision of the world.

View Bruno Figueiredo's profile on LinkedIn

TwitterCounter for @brunoshine
 
Creative Commons License

 
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.
 

Ads

    Page List

      Most comments

      busby seo test busby seo test
      6 comments
      us United States
      Busby SEO Test Busby SEO Test
      5 comments
      Busby SEO Test Busby SEO Test
      5 comments

      Popuri.us

      My Popularity (by popuri.us)