Click here to Skip to main content
Click here to Skip to main content

Preprocessor Directives in C#

, 29 Feb 2012
Rate this:
Please Sign up or sign in to vote.
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

#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

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

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

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

#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.

#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.

#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:

Fig-1
#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.

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

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

Fig-2

The regions can be understood from the following figure:

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)

About the Author

Sridhar Patnayak
Software Developer (Senior)
India India
Experienced IT professional in VB,C#,ASP.net,MVC,Remoting and WCF.
Follow on   Twitter

Comments and Discussions

 
GeneralMy vote of 1 PinmemberAlexWang201024-Jun-14 11:25 
QuestionCannot understand how this article explained well Pinpremiumcomiscience8-Jun-14 22:15 
QuestionNice article PinmemberWuRunZhe11-Dec-13 1:56 
GeneralGreat example PinmemberMember 94409601-Dec-13 16:13 
QuestionMy Vote of 5 PinmemberScrappy 187128-Nov-13 9:33 
GeneralMy vote of 5 Pinmembermanoj.jsm10-Jun-13 21:17 
GeneralRe: My vote of 5 PinmemberSridhar Patnayak10-Jun-13 22:55 
GeneralMy vote of 4 Pinmemberjohannesnestler2-May-13 2:58 
GeneralRe: My vote of 4 PinmemberSridhar Patnayak5-May-13 22:49 
SuggestionI don't think this is the right way of writing c-sharp code Pinmemberls2514513-Sep-12 22:04 
GeneralRe: I don't think this is the right way of writing c-sharp code Pinmemberjohannesnestler2-May-13 2:48 
GeneralMy vote of 1 Pinmemberwb12-Mar-12 23:14 
GeneralRe: My vote of 1 Pinmemberjohannesnestler2-May-13 2:44 
GeneralRe: My vote of 1 Pinmemberwb12-May-13 23:42 
GeneralRe: My vote of 1 [modified] Pinmemberjohannesnestler13-May-13 4:50 
GeneralNice ! Pinmemberraananv10-Mar-12 8:18 
10x for share ! Laugh | :laugh:
GeneralMy vote of 5 PinmemberAnurag Gandhi29-Feb-12 22:11 
GeneralMy vote of 4 Pinmemberamitgajjar29-Feb-12 17:29 
GeneralMy vote of 5 PinmemberAkram El Assas29-Feb-12 12:36 
GeneralMy vote of 5 Pinmemberonurag192-Feb-12 8:16 
GeneralRe: My vote of 5 PinmemberSridhar Patnayak2-Feb-12 18:10 
QuestionNice PinmemberCIDev18-Jan-12 6:27 
GeneralMy vote of 5 PinmvpAbhinav S8-Jan-12 3:14 
GeneralRe: My vote of 5 PinmemberSridhar Patnayak10-Jan-12 17:13 
GeneralMy vote of 1 PinmemberCrawfis3-Jan-12 7:22 
GeneralMy vote of 5 PinmemberGowri Shankar Rao3-Jan-12 6:23 
GeneralMy vote of 3 Pinmembertecgoblin2-Jan-12 20:32 
GeneralNice Effort PinmemberRajesh Puli2-Jan-12 3:46 
GeneralRe: Nice Effort PinmemberSridhar Patnayak2-Jan-12 6:18 
GeneralMy vote of 5 PinmemberRajesh Puli2-Jan-12 3:45 
GeneralRe: My vote of 5 PinmemberRajesh Anuhya26-Jan-12 23:45 
GeneralRe: My vote of 5 PinmemberSridhar Patnayak27-Jan-12 1:36 
GeneralMy vote of 5 PinmemberMonjurul Habib27-Dec-11 10:25 
GeneralRe: My vote of 5 PinmemberSridhar Patnayak27-Dec-11 17:46 
QuestionPlease do not write code like this! PinmemberSledgeHammer0127-Dec-11 4:49 
AnswerRe: Please do not write code like this! PinmemberSGarratt27-Dec-11 9:05 
GeneralRe: Please do not write code like this! PinmemberSledgeHammer0127-Dec-11 9:15 
GeneralRe: Please do not write code like this! PinmemberSridhar Patnayak27-Dec-11 18:16 
GeneralRe: Please do not write code like this! PinmemberJoeEspo3-Jan-12 5:13 
GeneralRe: Please do not write code like this! PinmemberPaul893-Jan-12 7:05 
GeneralRe: Please do not write code like this! PinmemberAhmed.mb13-Mar-12 7:16 
GeneralRe: Please do not write code like this! PinmemberJoeEspo13-Mar-12 7:44 
GeneralRe: Please do not write code like this! PinmemberAhmed.mb13-Mar-12 9:12 
GeneralRe: Please do not write code like this! PinmemberPIEBALDconsult26-Dec-12 7:04 
AnswerRe: Please do not write code like this! PinmemberRajesh Puli2-Jan-12 3:44 
AnswerRe: Please do not write code like this! Pinmemberjohannesnestler2-May-13 2:58 
GeneralMy vote of 5 Pinmemberravindradonkada27-Dec-11 1:52 
Generalnice and thanks for sharing the valuable info Pinmembersudhansu_k12326-Dec-11 22:56 
GeneralRe: nice and thanks for sharing the valuable info PinmemberSridhar Patnayak27-Dec-11 17:46 
GeneralMy vote of 5 PinmemberMadhuCodePro26-Dec-11 18:20 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 29 Feb 2012
Article Copyright 2011 by Sridhar Patnayak
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid