24.1 Conditional compilation With define , undef , if and endif


24.1 Conditional compilation With #define , #undef , #if and #endif

You use #define to declare a symbol. You can think of a symbol as a variable which is declared but not given a value. These symbols are used only by the C# compiler and have no effect at all on other parts of the source code.

Used in isolation, #define does not make sense but when used with #if and #endif , you can determine if blocks of source code, delimited by #if and #endif , will be included into your final IL codes after compilation. Here is an example:

 1:  #define DEBUG  2:  3: using System;   4:   5: public class TestClass{   6:   7:   public static void Main(){  8:  #if DEBUG   9:     Console.WriteLine("in Main");  10:  #endif   11:     Console.WriteLine("running statement");   12:   }   13: }  

Output:

 c:\expt>test in Main running statement 

Line 1 #define s the DEBUG symbol. During precompilation parsing, line 9 is included in the IL codes because the #if directive on line 8 is true (since symbol DEBUG has been defined.) The lines in the source file which eventually make it into IL codes are shown shaded. (Note that the preprocessor directive statements themselves are used only by the compiler, and never included in the final IL codes.)

If you comment off line 1, the output changes:

 1:  // #define DEBUG  DEBUG is no longer a defined symbol  2:  3: using System;   4:   5: public class TestClass{   6:   7:   public static void Main(){   8: #if DEBUG  9:     Console.WriteLine("in Main"); 10:  #endif   11:     Console.WriteLine("running statement");   12:   }   13: }  

Output:

 c:\expt>test running statement 

During precompilation parsing, it is determined that #if DEBUG on line 8 is false (since no such symbol has been previously defined with line 1 commented off) and so all the lines between #if DEBUG (line 8) and the next #endif (line 10) are not taken into consideration during compilation. Similarly, the shaded lines are those which eventually make it into IL codes.

The preprocessor directives introduced so far are often used for debugging and versioning purposes, as in the example shown (though other uses are left to your creativity).

Additional notes

  • Symbols are case sensitive “ by convention, symbols are named using all upper case letters .

  • Any #define statement must be made before any type declaration in the source file. You can have multiple #define statements.

  • Preprocessor directives do not end with semicolons. Each preprocessor directive must start on a new line.

  • If you attempt to #define a symbol that has already been #defined , nothing happens.

  • If you attempt to #undef a symbol that has not been previously #define d, nothing happens either.

  • You can use any identifier for symbol names, including C# keywords and actual identifier names used in the same source code (though this is highly discouraged because it can be confusing).

  • #if can be nested, but each #if must have a corresponding #endif directive statement.

Preprocessor directives are read by the compiler from top to bottom regardless of what source codes are in between. You can treat it as if the compiler parses a source file twice: once to check for preprocessor directives and remove all those source codes which should not appear in the final source file; the second parse actually performs the compilation.



From Java to C#. A Developers Guide
From Java to C#: A Developers Guide
ISBN: 0321136225
EAN: 2147483647
Year: 2003
Pages: 221
Authors: Heng Ngee Mok

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net