📜  C#预处理程序指令

📅  最后修改于: 2020-10-06 09:37:23             🧑  作者: Mango

在本教程中,我们将学习预处理器指令,C#中的可用指令以及何时,为什么以及为什么使用它们。

顾名思义,预处理器指令是在实际编译开始之前进行处理的语句块。 C#预处理程序指令是影响编译过程的编译器命令。

这些命令指定要编译的代码部分或如何处理特定的错误和警告。

C#预处理程序指令以# (hash)符号开头,并且所有预处理程序指令都持续一行。预处理器指令以new line而不是semicolon终止。

C#中可用的预处理器指令为:

Preprocessor directives in C#
Preprocessor Directive Description Syntax
#if Checks if a preprocessor expression is true or not
#if preprocessor-expression
code to compile
#endif
#elif Used along with #if to check multiple preprocessor expressions
#if preprocessor-expression-1
code to compile
#elif preprocessor-expression-2
code to compile
#endif
#else Used along with #if to create compound conditional directive.
#if preprocessor-expression
code to compile
#elif
code to compile
#endif
#endif Used along with #if to indicate the end of a conditional directive
#if preprocessor-expression
code to compile
#endif
#define Used to define a symbol
#define SYMBOL
#undef Used to undefine a symbol
#undef SYMBOL
#warning Allows us to generate level 1 warning from our code
#warning warning-message
#error Allows us to generate error from our code
#error error-message
#line Allows us to modify the compiler’s line number and filename to display errors and warnings
#line line-number file-name
#region Allows us to create a region that can be expanded or collapsed when using a Visual Studio Code Editor
#region region-description
codes
#endregion
#endregion Indicates the end of a region
#region region-description
codes
#endregion
#pragma Gives the compiler special instructions for the compilation of the file in which it appears.
#pragma pragma-name pragma-arguments

#define指令
  • #define指令允许我们定义符号。
  • #if指令一起使用时定义的符号将计算为true。
  • 这些符号可用于指定编译条件。
  • 句法:
    #define SYMBOL
  • 例如:
    #define TESTING

#undef指令
  • #undef指令允许我们#undef定义符号。
  • #if指令一起使用时,未定义的符号将计算为false。
  • 句法:
    #undef SYMBOL
  • 例如:
    #undef TESTING

#if指令
  • #if指令用于测试预处理器表达式。
  • 预处理器表达式可以仅包含一个符号,也可以包含符号的组合以及运算符,例如&& (AND), || (或) ! (不)。
  • #if指令后跟#endif指令。
  • 仅当使用#if测试的表达式的值为true时,才会编译#if指令中的代码。
  • 句法:
    #if preprocessor-expression
        code to compile<
    #endif
  • 例如:
    #if TESTING
        Console.WriteLine("Currently Testing");
    #endif

示例1:如何使用#if指令?

#define CSHARP

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

当我们运行程序时,输出将是:

CSHARP is defined

在上述程序中, CSHARP符号是在程序开头使用#define指令定义的。在Main()方法内部,使用#if指令测试CSHARP是否为true。仅在定义CSHARP情况下,才编译#if指令内的代码块。


#elif指令
  • #elif指令与#if指令一起使用,可让我们创建复合条件指令。
  • 在测试多个预处理器表达式时使用它。
  • 仅在使用#elif测试的表达式为true时,才编译#elif指令中的代码。
  • 句法:
    #if preprocessor-expression-1
        code to compile
    #elif preprocessor-expression-2
        code-to-compile
    #endif
  • 例如:
    #if TESTING
        Console.WriteLine("Currently Testing");
    #elif TRAINING
        Console.WriteLine("Currently Training");
    #endif

#else指令
  • #else指令与#if指令一起使用。
  • 如果前面的#if#elif (如果存在)指令中的表达式都不为真,则将编译#else指令中的代码。
  • 句法:
    #if preprocessor-expression-1
        code to compile
    #elif preprocessor-expression-2
        code-to-compile
    #else
        code-to-compile
    #endif
  • 例如:
    #if TESTING
        Console.WriteLine("Currently Testing");
    #elif TRAINING
        Console.WriteLine("Currently Training");
    #else
        Console.WriteLine("Neither Testing nor Training");
    #endif

#endif指令
  • #endif指令兼用#if指令来指示结束#if指令。
  • 句法:
    #if preprocessor-expression-1
        code to compile
    #endif
  • 例如:
    #if TESTING
        Console.WriteLine("Currently Testing");
    #endif

示例2:如何使用条件指令(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
        }
    }
}

当我们运行程序时,输出将是:

CSHARP is defined, PYTHON is undefined

在此示例中,我们可以看到#elif#else指令的使用。当有多个条件要测试时,将使用这些指令。同样,可以使用逻辑运算符将符号合并以形成预处理器表达式。


#warning指令
  • #warning指令允许我们从代码中生成用户定义的一级警告。
  • 句法:
    #warning warning-message
  • 例如:
    #warning This is a warning message

示例3:如何使用#warning指令?

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

当我们运行程序时,输出将是:

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

运行上面的程序后,我们将看到上面的输出。文本表示警告消息。在这里,我们正在使用#warning指令生成用户定义的警告消息。

请注意,# #warning指令之后的语句也将执行。这意味着#warning指令不会终止程序,而只会引发警告。


#error指令
  • #error指令允许我们从代码中生成用户定义的错误。
  • 句法:
    #error error-message
  • 例如:
    #error This is an error message

示例4:如何使用#error指令?

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

当我们运行程序时,输出将是:

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.

我们将看到一些错误,可能与上面类似。在这里,我们正在生成用户定义的错误。

这里要注意的另一件事是程序将终止,并且不会像在#warning指令中那样显示#error directive example行。


#line指令
  • #line指令允许我们修改行号和文件名以获取错误和警告。
  • 句法:
    #line line-number file-name
  • 例如:
    #line 50 "fakeprogram.cs"

示例5:如何使用#line指令?

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
        }
    }
}

当我们运行程序时,输出将是:

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]

我们将上面的示例保存为Program.cs 。该警告实际上是由Program.csline 10生成的。使用#line指令,我们已将行号更改为200 ,并将文件名更改为生成错误的AnotherProgram.cs


#region和#endregion指令
  • #region指令允许我们创建一个在使用Visual Studio代码编辑器时可以扩展或折叠的区域。
  • 该指令仅用于组织代码。
  • #region块不能与#if块重叠。然而, #region块可以被包括在#if块内,并且#if块可以与#region块重叠。
  • #endregion指令指示#region块的结尾。
  • 句法:
    #region region-description
        codes
    #endregion

示例6:如何使用#region指令?

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
        }
    }
}

当我们运行程序时,输出将是:

Hello
Hello
Hello
Hello
Hello

#pragma指令
  • #pragma指令用于为编译器提供一些特殊的指令,用于编译该文件所在的文件。
  • 该指令可以包括禁用或启用某些警告。
  • C#支持两条#pragma指令:
    • #pragma warning :用于禁用或启用警告
    • #pragma checksum :它为将用于调试的源文件生成校验和。
  • 句法:
    #pragma pragma-name pragma-arguments
  • 例如:
    #pragma warning disable

    示例7:如何使用#pragma指令?

    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
            }
        }
    }
    

    当我们运行程序时,输出将是:

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

    我们可以看到在输出屏幕上仅显示第二个警告

    这是因为,我们最初禁用了第一个警告之前的所有警告,而仅在第二个警告之前将它们还原。这就是隐藏第一个警告的原因。

    我们还可以禁用特定警告而不是所有警告。

    要了解有关#pragma更多信息,请访问#pragma(C#参考)。