YouTip LogoYouTip

Csharp Preprocessor Directives

C# Preprocessor Directives

Preprocessor Directives guide the compiler to preprocess information before the actual compilation begins.

Through these directives, you can control how the compiler compiles a file or which parts to compile. Common preprocessor directives include conditional compilation, macro definitions, etc.

All preprocessor directives start with a # and are on a single line. Only whitespace characters can appear before a preprocessor directive.

Preprocessor directives are not statements, so they do not end with a semicolon (;).

The C# compiler does not have a separate preprocessor, but the directives are processed as if there were one. In C#, preprocessor directives are used for conditional compilation. Unlike C and C++, they are not used to create macros. A preprocessor directive must be the only directive on its line.

The following table lists the preprocessor directives available in C#:

Directive Description
#define Defines a symbol that can be used for conditional compilation.
#undef Undefines a symbol.
#if Begins a conditional compilation block, including the code block if the symbol is defined.
#elif Includes the code block if the preceding #if or #elif condition is not met and the current condition is met.
#else Includes the code block if the preceding #if or #elif condition is not met.
#endif Ends a conditional compilation block.
#warning Generates a compiler warning message.
#error Generates a compiler error message.
#region Marks a block of code that can be collapsed and expanded in an IDE, aiding in code organization and readability.
#endregion Ends a code region.
#line Changes the line number and file name in the compiler output, useful for debugging or code generation tools.
#pragma Used to send special instructions to the compiler, such as disabling or restoring specific warnings.
#nullable Controls the nullable context and annotations, allowing the enabling or disabling of compiler checks for nullable reference types.

Example

#define DEBUG

#if DEBUG
    Console.WriteLine("Debug mode");
#elif RELEASE
    Console.WriteLine("Release mode");
#else
    Console.WriteLine("Other mode");
#endif

#warning This is a warning message
#error This is an error message

#region MyRegion
// Your code here
#endregion

#line 100 "MyFile.cs"
// The next line will be reported as line 100 in MyFile.cs
    Console.WriteLine("This is line 100");
#line default
// Line numbering returns to normal

#pragma warning disable 414
private int unusedVariable;
#pragma warning restore 414

#nullable enable
string? nullableString = null;
#nullable disable

#define is used to define a symbol (typically for conditional compilation), and #undef is used to undefine a symbol.

#define DEBUG
#undef RELEASE

#define allows you to define a symbol so that, by using the symbol as an expression passed to the #if directive, the expression will return true. Its syntax is as follows:

#define symbol

The following program illustrates this:

Example

#define PI

using System;

namespace PreprocessorDAppl
{
    class Program
    {
        static void Main(string[] args)
        {
#if (PI)
            Console.WriteLine("PI is defined");
#else
            Console.WriteLine("PI is not defined");
#endif
            Console.ReadKey();
        }
    }
}

When the above code is compiled and executed, it produces the following result:

PI is defined

You can use the #if directive to create a conditional directive.

Conditional directives are used to test whether a symbol is true. If it is true, the compiler executes the code between #if and the next directive.

The syntax for conditional directives is:

#if symbol ...

Where symbol is the name of the symbol to test. You can also use true and false, or place a negation operator before the symbol.

Common operators include:

  • == (equality)
  • != (inequality)
  • && (logical AND)
  • || (logical OR)

You can also group symbols and operators with parentheses. Conditional directives are used to compile code for debug builds or when a specific configuration is specified. A conditional directive starting with a #if directive must be explicitly terminated with a #endif directive.

#define DEBUG
#if DEBUG
Console.WriteLine("Debug mode");
#elif RELEASE
Console.WriteLine("Release mode");
#else
Console.WriteLine("Other mode");
#endif

The following program demonstrates the use of conditional directives:

Example

#define DEBUG
#define VC_V10

using System;

public class TestClass
{
    public static void Main()
    {
#if (DEBUG && !VC_V10)
        Console.WriteLine("DEBUG is defined");
#elif (!DEBUG && VC_V10)
        Console.WriteLine("VC_V10 is defined");
#elif (DEBUG && VC_V10)
        Console.WriteLine("DEBUG and VC_V10 are defined");
#else
        Console.WriteLine("DEBUG and VC_V10 are not defined");
#endif
        Console.ReadKey();
    }
}

When the above code is compiled and executed, it produces the following result:

DEBUG and VC_V10 are defined

#warning is used to generate a compiler warning, and #error is used to generate a compiler error.

#warning This is a warning message
#error This is an error message

Used for code folding to make code more readable.

#region MyRegion
// Your code here
#endregion

Used to change the line number and file name in the compiler output.

#line 100 "MyFile.cs"
// The next line will be reported as line 100 in MyFile.cs
Console.WriteLine("This is line 100");
#line default
// Line numbering returns to normal

Used to send special instructions to the compiler. The most common use is to disable specific warnings.

#pragma warning disable 414
private int unusedVariable;
#pragma warning restore 414

  • Improve Code Readability: Using #region can help separate code blocks and improve code organization.
  • Conditional Compilation: Through directives like #if, different code can be compiled for development and production environments, facilitating debugging and release.
  • Warnings and Errors: Through #warning and #error, developers can be alerted to specific issues during compilation.

By correctly using these preprocessor directives, you can better control the code compilation process, improving code flexibility and maintainability.

← Csharp Regular ExpressionsProp Tableheader Rowspan β†’