Wednesday, September 19, 2007

#if DEBUG vs. [Conditional("DEBUG")]


 
    1 using System;
    2 using System.Diagnostics;
    3 public class IFDebug
    4 {
    5 #if DEBUG 
    6   public int Method ()
    7   {
    8     return 5;
    9   }
   10 
   11 #endif
   12     //error CS0578: The Conditional attribute is not valid on 
   13     //'IFDebug.Method2()' because its return type is not void 
   14     /* 
   15   [Conditional("DEBUG")] 
   16   public int Method2() 
   17   { 
   18   return 5; 
   19   }*/
   20 #if DEBUG 
   21   public void Method3 ()
   22   {
   23   }
   24 
   25 #endif
   26     [Conditional("DEBUG")]
   27     public static void Method4()
   28     {
   29     }
   30 
   31 }
   32 
   33 
   34 #if DEBUG 
   35 public class IFDebug2 {
   36 }
   37 
   38 
   39 #endif
   40 //ifdebug.cs(28,2): error CS1689: Attribute 
   41 //'System.Diagnostics.ConditionalAttribute' is
   42 //only valid on methods or attribute classes 
   43 /* 
   44 [Conditional("DEBUG")] 
   45 public class IFDebug3 
   46 { 
   47 }*/
   48 //So, let's compare apples to apples 
   49 #if DEBUG 
   50 public class IFDebug3 : Attribute{
   51 }
   52 #endif
   53 
   54 [Conditional("DEBUG")]
   55 public class IFDebug4 : Attribute
   56 {
   57     public IFDebug4()
   58     {
   59         IFDebug.Method4();
   60     }
   61 
   62 }
   63 

Consider the above code.  Let's say I compile it with

c:\> csc /t:library /define:DEBUG ifdebug.cs

The ILDASM screenshot looks like this:

ifdebug-6

 

What if I do a RELEASE build?

ifdebug-3

 

So, it simply means that [Conditional("DEBUG")] classes get carried to RELEASE builds.  But is that all?  Nope... Calls to methods adorned with Conditional("DEBUG"), evaporate - disappear - in RELEASE builds.  Here are the screenshots from Reflector:

 

ifdebug-7 ifdebug-8


How is it useful?  Practical usage?  Wait for my next post :)

1 comment:

Maeztro said...

The conditional DEBUG methods get carried to RELEASE builds when those are defined "public" (which makes sense because it could be used/referenced in another context). Although, I don't think (not verified) the same behavior shows up for private methods.