C# Preprocessor Directives: In this tutorial, we’ll learn about Preprocessor Directives, accessible directives in C#, and when, why and how why they are used.

What is a preprocessor directives

C# preprocessor directives are commands that affect the compilation interaction and are prepared before compilation. Even through the compiler doesn’t have a separate preprocessor, the directives are processed as though there were one.


As the name justifies, preprocessor directives are a block of statements that gets prepared before the actual compilation begins. C# preprocessor directives are the commands for the compiler that influences the compilation process.

These commands specifies what segments of the code to compile or how to deal with explicit errors and warnings.

C# preprocessor directive starts with a # (hash) symbol and all preprocessor directives keep going for one line. Preprocessor directives are terminated by new line instead of semicolon.

The preprocessor directives accessible in C# are:

Preprocessor directives in C#

Preprocessor Directive  Description         Syntax

#ifChecks if a preprocessor expression is true or not
#if preprocessor-expression
	code to compile
#endif
#elifUsed along with #if to check multiple preprocessor expressions
#if preprocessor-expression-1
	code to compile
#elif preprocessor-expression-2
	code to compile
#endif
#elseUsed along with #if to create compound conditional directive.
#if preprocessor-expression
	code to compile
#elif
	code to compile
#endif
#endifUsed along with #if to indicate the end of a conditional directive
#if preprocessor-expression
	code to compile
#endif
#defineUsed to define a symbol
#define SYMBOL
#undefUsed to undefine a symbol
#undef SYMBOL
#warningAllows us to generate level 1 warning from our code
#warning warning-message
#errorAllows us to generate error from our code
#error error-message
#lineAllows us to modify the compiler’s line number and filename to display errors and warnings
#line line-number file-name
#regionAllows us to create a region that can be expanded or collapsed when using a Visual Studio Code Editor
#region region-description
	codes
#endregion
#endregionIndicates the end of a region
#region region-description
	codes
#endregion
#pragmaGives the compiler special instructions for the compilation of the file in which it appears.
#pragma pragma-name pragma-arguments

#define directive

The #define directive allows us to characterize a symbol.

Symbols that are characterized when used alongside #if directive will assess to true.

These symbols can be used to indicate conditions for compilation.

Syntax:

#define SYMBOL

For instance:

#define TESTING

Here, TESTING is a symbol.


#undef directive

The #undef directive allows us to undefine a symbol.

Undefined symbols when used alongside #if directive will assess to false.

Syntax:

#undef SYMBOL

For instance:

#undef TESTING

Here, TESTING is a symbol.


#if directive

The #if directive are used to test the preprocessor expression.

A preprocessor expression may comprises of a symbol in particular or combination of symbols alongside operators like && (AND), || (OR), ! (NOT).

#if directive is followed by an #endif directive.

The codes inside the #if directive is compiled just if the expression tried with #if assesses to true.

Syntax:

#if preprocessor-expression
	code to compile<
#endif

For instance:

#if TESTING
	Console.WriteLine("Currently Testing");
#endif

Example 1: How to use #if directive?

#define CSHARP

using System;
 
namespace Directive
{
	class ConditionalDirective
	{
		public static void Main(string[] args)
		{
			#if (CSHARP)
				Console.WriteLine("CSHARP is defined");
			#endif
		}
	}
}

At the point when we run the program, the output will be:

CSHARP is defined

In the above program, CSHARP symbol is characterized using the #define directive toward the start of program. Inside the Main() strategy, #if directive is used to test if CSHARP is true. The block of code inside #if directive is arranged just if CSHARP is defined.


#elif directive

The #elif directive is used alongside #if directive that allows us to create a compound conditional directive.

It is used when testing different preprocessor expression.

The codes inside the #elif directive is compiled just if the expression tried with that #elif assesses to true.

syntax:

#if preprocessor-expression-1
	code to compile
#elif preprocessor-expression-2
	code-to-compile
#endif

For instance:

#if TESTING
	Console.WriteLine("Currently Testing");
#elif TRAINING
	Console.WriteLine("Currently Training");
#endif

#else directive

The #else directive is used alongside #if directive.

On the off chance that none of the expression in the first #if and #elif (if present) directives are true, the codes inside the #else directive will be compiled.

Syntax:

#if preprocessor-expression-1
	code to compile
#elif preprocessor-expression-2
	code-to-compile
#else
	code-to-compile
#endif

For instance:

#if TESTING
	Console.WriteLine("Currently Testing");
#elif TRAINING
	Console.WriteLine("Currently Training");
#else
	Console.WriteLine("Neither Testing nor Training");
#endif

#endif directive

The #endif directive is used alongside #if directive to show the finish of #if directive.

Syntax:

#if preprocessor-expression-1
	code to compile
#endif

For instance:

#if TESTING
	Console.WriteLine("Currently Testing");
#endif

Example 2: How to use conditional directive (if, elif, else, endif) ?

#define CSHARP
#undef PYTHON
 
using System;
 
namespace Directive
{
	class ConditionalDirective
	{
		static void Main(string[] args)
		{
			#if (CSHARP && PYTHON)
				Console.WriteLine("CSHARP and PYTHON are defined");
			#elif (CSHARP && !PYTHON)
				Console.WriteLine("CSHARP is defined, PYTHON is undefined");
			#elif (!CSHARP && PYTHON)
				Console.WriteLine("PYTHON is defined, CSHARP is undefined");
			#else
				Console.WriteLine("CSHARP and PYTHON are undefined");
			#endif
		}
	}
}

At the point when we run the program, the output will be:

CSHARP is defined, PYTHON is undefined

In this example, we can see the use of #elif and #else directive. These directive are used when there are different conditions to be tried. Additionally, symbols can be combined using logical operators to form a preprocessor expression.


#warning directive

The #warning directive allows us to create a user-defined level one warning from our code.

Syntax:

#warning warning-message

For example

#warning This is a warning message

Example 3: How to use #warning directive?

using System;
 
namespace Directives
{
	class WarningDirective
	{
		public static void Main(string[] args)
		{
			#if (!CSHARP)
				#warning CSHARP is undefined
			#endif
			Console.WriteLine("#warning directive example");
		}
	}
}

At the point when we run the program, the output will be:

Program.cs(10,26): warning CS1030: #warning: 'CSHARP is undefined' [/home/myuser/csharp/directives-project/directives-project.csproj]
#warning directive example

Subsequent to running the above program, we will consider the to be as above. The content addresses a warning message. Here, we are producing a user-defined warning message using the #warning directive.

Note that the statements after the #warning directive are additionally executed. It implies that the #warning directive doesn’t end the program but just throws a warning.


#error directive

The #error directive allows us to generate a user-defined error from our code.

syntax

#error error-message

For instance:

#error This is an error message

Example 4: How to use #error directive?

using System;
 
namespace Directive
{
	class Error
	{
		public static void Main(string[] args)
		{
			#if (!CSHARP)
				#error CSHARP is undefined
			#endif
			Console.WriteLine("#error directive example");
		}
	}
}

At the point when we run the program, the output will be:

Program.cs(10,24): error CS1029: #error: 'CSHARP is undefined' [/home/myuser/csharp/directives-project/directives-project.csproj]
The build failed. Please fix the build errors and run again.

We will see a few errors, presumably like above. Here we are creating a user-defined error.

Something else to note here is the program will be ended and the line #error directive example will not be printed as it was in the #warning directive.


#line directive

The #line directive allows us to alter the line number and the filename for errors and warning.

Syntax:

#line line-number file-name

For instance:

#line 50 "fakeprogram.cs"

Example 5: How to use #line directive?

using System;
 
namespace Directive
{
	class Error
	{
		public static void Main(string[] args)
		{
			#line 200 "AnotherProgram.cs"
			#warning Actual Warning generated by Program.cs on line 10
		}
	}
}

At the point when we run the program, the output will be:

AnotherProgram.cs(200,22): warning CS1030: #warning: 'Actual Warning generated by Program.cs on line 10' [/home/myuser/csh
arp/directive-project/directive-project.csproj]

We have saved the above example as Program.cs. The warning was actually created at line 10 by Program.cs. Using the #line directive, we have changed the line number to 200 and the filename to AnotherProgram.cs that created the error.


#region and #endregion directive

The #region directive allows us to create an area that can be extended or collapsed when using a Visual Studio Code Editor.

This directive is basically used to coordinate the code.

The #region block can not cover with a #if block. Be that as it may, a #region block can be incorporated inside a #if block and a #if block can cover with a #region block.

#endregion directive indicates the end of a #region block.

Syntax:

#region region-description
	codes
#endregion

Example 6: How to use #region directive?

using System;
 
namespace Directive
{
	class Region
	{
		public static void Main(string[] args)
		{
			#region Hello
			Console.WriteLine("Hello");
			Console.WriteLine("Hello");
			Console.WriteLine("Hello");
			Console.WriteLine("Hello");
			Console.WriteLine("Hello");
			#endregion
		}
	}
}

At the point when we run the program, the output will be:

Hello
Hello
Hello
Hello
Hello

#pragma directive

The #pragma directive is used to give the compiler some unique guidelines for the compilation of the file where it shows up.

The instruction may incorporate disabling or enabling a few warnings.

C# supports two #pragma directions:

#pragma warning: Used for disabling or enabling warnings
#pragma checksum: It generates checksums for source files which will be used for debugging.

Syntax:

#pragma pragma-name pragma-arguments

For instance:

#pragma warning disable

Example 7: How to use #pragma directive?

using System;
 
namespace Directive
{
	class Error
	{
		public static void Main(string[] args)
		{
			#pragma warning disable
			#warning This is a warning 1
			#pragma warning restore
			#warning This is a warning 2
		}
	}
}

At the point when we run the program, the output will be:

Program.cs(12,22): warning CS1030: #warning: 'This is a warning 2' [/home/myuser/csharp/directive-project/directive-project.csproj]

We can see that lone the second warning is shown on the output screen.

This is on the grounds that, we at first disabled all warnings before the first warning and restored them just before the second warning. This is the reason why the first warning was hidden.

We can likewise disable specific warning rather than all warning.

To learn more about #pragma, visit #pragma (C# reference).


Thanks for reading! We hope you found this tutorial helpful and we would love to hear your feedback in the Comments section below. And show us what you’ve learned by sharing your photos and creative projects with us.