Click here to Skip to main content
15,868,016 members
Articles / Web Development / ASP.NET

Preprocessor Directives in C#

Rate me:
Please Sign up or sign in to vote.
4.66/5 (47 votes)
29 Feb 2012CPOL3 min read 176.7K   1.6K   109   55
To explain Preprocessor directives in C#

Introduction

Preprocessor directives are commands that are interpreted by the compiler and affect the output or behavior of the build process. But the C# compiler does not have a separate preprocessor, like C and C++ you cannot use these directives to create macros. Preprocessing directives are top lines in our program that start with '#'. The '#' is followed by an identifier that is the directive name.

.NET framework 1.1 and above will support these preprocessor directives.

Classification of C# language preprocessor directives are as follows.

Conditional compilation: We can include and exclude parts of the program based on the conditions.

  • #if
  • #else
  • #elif
  • #endif
  • #define
  • #undef

Errors , Warnings , Line & pragma: The directive #error initiates the preprocessor to rise error, #warning like #error directive but it prompts warning to the user and continues with the process, #line can be used to hide sections of code from the debugger. The #pragma directive can either suppress or restore specific compiler warnings.

  • #warning
  • #error
  • #line
  • #pragma

Region: If you want to indicate a certain block of source code with a name, you can indicate it with a name and keep the entire block between #region and #endregion. So the C# code file is neatly organized as blocks, and that can be expanded or collapsed visually.

  • #region
  • #endregion

Real Time Usage

When I work with real time environment, the preprocessor directives are very helpful to set conditional compilation like setting up of default parameters based on the defined symbol, and prompting developers in terms of building project, and making conditional warnings and errors, etc.

Sample program to demonstrate it

C#
#define Default
#define DevelopmentMode
#define TestingMode
#undef  Development

#if DEBUG
#warning You should not compile in debug mode, use release mode         
#endif
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SampleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            String orgName=String.Empty;
            String email=String.Empty;
            String SourceDb=String.Empty;

            #if(DevelopmentMode)
              {
              SourceDb="C:\\DovDb.Mdb"; //This Db used at the time of development phase
              }
            #else
              {
              SourceDb = "C:\\TestDb.Mdb";//This Db used at the time of testing
              }
            #endif


            #if(Default)
            {
                orgName = "MyOrganization";            
                email = "Default@gmail.com";
                const string logName = @"\myLog.log";  //Write log information
            }
            #else
            {   
                orgName = fetch from database
                email = fetch from database
               const string logName = fetch from database //Write log information
            }
            #endif
        }       
    }
}

Preprocessor directives help the developer to make programming with minimal complexity, improving readability, ease Of maintenance, and prompting invalid changes in the flow of code, etc.

Using the Code

I am going to provide a simple application which will enable you to better understand preprocessor directives in C#, and how we can use it in the real time environment.

In the following, there are 3 private assemblies, viz., version0, version1 and version2. Version0 takes input data from the user. A new feature “AddOperation” is added in Version1 based on the user input values. Version2 has added new feature “SubOperation” and changed the existing “AddOperation” with the default values.

So the users who are going to use “AddOperation” based on the user input values can use version2, but they don’t get the new feature of “SubOperation”.

The following code demonstrates it.

Version0

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PreproDirective
{
    class NumberOperationVersion0
    {
        Int32 x, y;
        public void GetData(Int32 x, Int32 y)
        {
            this.x = x;
            this.y = y;

        }
        public Int32 AddOperation()
        {
            //Not implemented
            return 0;
        }

        public Int32 SubOperation()
        {
            //Not implemented
            return 0;
        }
    }
}

The above version0 has the feature to take data from the user but does not have any operations.

Version1

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PreproDirective
{
    public class NumberOperationVersion1
    {
        Int32 x, y;
        public void GetData(Int32 x,Int32 y)
        {
            this.x = x;
            this.y = y;
        }
        public Int32 AddOperation() 
        {
    //Operation performed based on User input values 
            return x + y;
        }
        public Int32 SubOperation()
        {
            //Not implemented in this version1
            return 0;
        }
    }
}

This version1 adds "AddOperation" feature by taking user input.

Version2

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PreproDirective
{
    public class NumberOperationVersion2
    {
        Int32 x, y;
        public void GetData(Int32 x,Int32 y)
        {
            this.x = x;
            this.y = y;
        }

        public Int32 AddOperation(Int32 x,Int32 y)
        {
//Operation performed based on default values passed from main program
            return x + y;
        }

        public Int32 SubOperation()
        {
            return x-y;
        }           
    }
}

This version2 implemented the feature "SubOperation", and changed "AddOperation" by taking default values.

Main Program

C#
#define version0   
#define version1
#define version2
#undef  version0      // if you comment it,  error raised

#if DEBUG
#warning Compiled in DEBUG mode.      // use release mode to prevent this warning
#endif

#if version0
#error Version0 is not working.    //Error will be raised when version0 is defined
#endif

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PreproDirective
{
    class Program
    {
        static void Main(string[] args)
        {
            Int32 x=0,y=0;

                #pragma warning disable
                       #line 20 "NumberOperationVersion1.cs"
                       #warning "Changes in Earlier versions are not allowed"
                       #line default
                #pragma warning restore

                #line 20 "NumberOperationVersion0.cs"
                #warning "Changes in version0 are not allowed"
                #line default

            //Version 1 changes
            #region V1
                    #if(version1)
                    {
                       NumberOperationVersion1 objVer1=new NumberOperationVersion1();
                       Console.WriteLine("Enter Xvalue,Yvalue to check version1
                       compatibility with ADD and Sub Operation");
                        
                        Console.WriteLine("Enter Xvalue:");
                        x=Convert.ToInt32(Console.ReadLine());

                        Console.WriteLine("Enter Yvalue:");
                        y = Convert.ToInt32(Console.ReadLine());
                        objVer1.GetData(x,y);
                    Console.WriteLine("AddOperation Result is:"+objVer1.AddOperation());
              Console.WriteLine("SubOperation is not working with this version \n\n\n\n");
                    }
                    #endif
            #endregion V1

             //Version 2 changes
            #region V2                              

                     #if (version2)
                       {
                         NumberOperationVersion2 objVer2=new NumberOperationVersion2();
                         Console.WriteLine("Enter Xvalue,Yvalue to check version2
                         compatibility with ADD and Sub Operation");
                         Console.WriteLine("Enter Xvalue:");
                         x = Convert.ToInt32(Console.ReadLine());

                         Console.WriteLine("Enter Yvalue:");
                         y = Convert.ToInt32(Console.ReadLine());
                         objVer2.GetData(x,y);
                        Console.WriteLine("AddOperation Result is(Based on the default
                        values version-2 is):"+objVer2.AddOperation(10,12));
                        Console.WriteLine("SubOperation Result is (Based on user input):"+
                        objVer2.SubOperation());
                    }
                    #else
                    {
                      Console.WriteLine("No Version found");
                    }
                    #endif

            #endregion V2                     
            Console.ReadKey();
        }
    }
}

On the top of the program, versions are defined, and the unused version0 is undefined.

C#
#if DEBUG
#warning Compiled in DEBUG mode.
#endif 

If we run the application in debug mode, it will throw a warning as shown in Fig.1.

C#
#if version0
#error Version0 is not working.    
#endif

If version0 is defined but unused, so it should be reversed to undefined; lest it will throw a fatal error as "Version0 is not working" shown in the Fig.1:

Image 1

Fig-1
C#
#pragma warning disable
#line 20 "NumberOperationVersion1.cs"
#warning "Changes in Earlier versions are not allowed"
#line default
#pragma warning restore 

In the main program, the above statement throws a warning at line number 20 in "NumberOperationVersion1.cs" class. But the statement “#pragma warning disable” will disable the warning.

C#
#line 20 "NumberOperationVersion0.cs"
#warning "Changes in version0 are not allowed"
#line default

Statement throws warning at line number 20 in "NumberOperationVersion0.cs" class:

Image 2

Fig-2

The regions can be understood from the following figure:

Image 3

Fig-3

The above program is taken to easily illustrate the working of preprocessor directives.

Conclusion

This article gives you a better understanding of preprocessor directives in C#. Hope to get your feedback and suggestions.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
India India
Experienced IT professional in VB,C#,ASP.net,MVC,Remoting and WCF.

Comments and Discussions

 
GeneralMy vote of 1 Pin
AlexWang201024-Jun-14 11:25
AlexWang201024-Jun-14 11:25 
QuestionCannot understand how this article explained well Pin
comiscience8-Jun-14 22:15
comiscience8-Jun-14 22:15 
QuestionNice article Pin
WuRunZhe11-Dec-13 1:56
WuRunZhe11-Dec-13 1:56 
GeneralGreat example Pin
Member 94409601-Dec-13 16:13
Member 94409601-Dec-13 16:13 
QuestionMy Vote of 5 Pin
Scrappy 187128-Nov-13 9:33
Scrappy 187128-Nov-13 9:33 
GeneralMy vote of 5 Pin
manoj.jsm10-Jun-13 21:17
manoj.jsm10-Jun-13 21:17 
GeneralRe: My vote of 5 Pin
Sridhar Patnayak10-Jun-13 22:55
professionalSridhar Patnayak10-Jun-13 22:55 
GeneralMy vote of 4 Pin
johannesnestler2-May-13 2:58
johannesnestler2-May-13 2:58 
GeneralRe: My vote of 4 Pin
Sridhar Patnayak5-May-13 22:49
professionalSridhar Patnayak5-May-13 22:49 
SuggestionI don't think this is the right way of writing c-sharp code Pin
ls2514513-Sep-12 22:04
ls2514513-Sep-12 22:04 
GeneralRe: I don't think this is the right way of writing c-sharp code Pin
johannesnestler2-May-13 2:48
johannesnestler2-May-13 2:48 
GeneralMy vote of 1 Pin
wb12-Mar-12 23:14
wb12-Mar-12 23:14 
GeneralRe: My vote of 1 Pin
johannesnestler2-May-13 2:44
johannesnestler2-May-13 2:44 
GeneralRe: My vote of 1 Pin
wb12-May-13 23:42
wb12-May-13 23:42 
GeneralRe: My vote of 1 Pin
johannesnestler13-May-13 4:50
johannesnestler13-May-13 4:50 
GeneralNice ! Pin
raananv10-Mar-12 8:18
raananv10-Mar-12 8:18 
GeneralMy vote of 5 Pin
Anurag Gandhi29-Feb-12 22:11
professionalAnurag Gandhi29-Feb-12 22:11 
GeneralMy vote of 4 Pin
AmitGajjar29-Feb-12 17:29
professionalAmitGajjar29-Feb-12 17:29 
GeneralMy vote of 5 Pin
Akram El Assas29-Feb-12 12:36
Akram El Assas29-Feb-12 12:36 
GeneralMy vote of 5 Pin
Anurag Sarkar2-Feb-12 8:16
Anurag Sarkar2-Feb-12 8:16 
GeneralRe: My vote of 5 Pin
Sridhar Patnayak2-Feb-12 18:10
professionalSridhar Patnayak2-Feb-12 18:10 
QuestionNice Pin
BillW3318-Jan-12 6:27
professionalBillW3318-Jan-12 6:27 
GeneralMy vote of 5 Pin
Abhinav S8-Jan-12 3:14
Abhinav S8-Jan-12 3:14 
GeneralRe: My vote of 5 Pin
Sridhar Patnayak10-Jan-12 17:13
professionalSridhar Patnayak10-Jan-12 17:13 
GeneralMy vote of 1 PinPopular
Crawfis3-Jan-12 7:22
Crawfis3-Jan-12 7:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.