# C# 预处理器指令

> 原文： [https://www.programiz.com/csharp-programming/preprocessor-directives](https://www.programiz.com/csharp-programming/preprocessor-directives)

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

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

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

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

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

Preprocessor directives in C#

`#if`

检查预处理器表达式是否为真

```cs
#if preprocessor-expression
	code to compile
#endif
```


`#elif`

与`#if`一起使用以检查多个预处理器表达式

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


`#else`

与`#if`一起使用以创建复合条件指令。

```cs
#if preprocessor-expression
	code to compile
#elif
	code to compile
#endif
```


`#endif`

与`#if`一起使用以指示条件指令的结尾

```cs
#if preprocessor-expression
	code to compile
#endif
```


`#define`

用于定义符号

```cs
#define SYMBOL
```


`#undef`

用于取消定义符号

```cs
#undef SYMBOL
```


`#warning`

允许我们从代码中生成 1 级警告

```cs
#warning warning-message
```


`#error`

允许我们从代码中生成错误

```cs
#error error-message
```


`#line`

允许我们修改编译器的行号和文件名以显示错误和警告

```cs
#line line-number file-name
```


`#region`

允许我们创建一个使用 Visual Studio 代码编辑器时可以扩展或折叠的区域

```cs
#region region-description
	codes
#endregion
```


`#endregion`

指示区域的结尾

```cs
#region region-description
	codes
#endregion
```


`#pragma`

为编译器提供特别的说明，以编译其中出现的文件。

```cs
#pragma pragma-name pragma-arguments
```



* * *

## `#define`指令

*   `#define`指令允许我们定义符号。
*   与`#if`伪指令一起使用时定义的符号将求值为`true`。
*   这些符号可用于指定编译条件。
*   **语法**：

    ```cs
    #define SYMBOL
    ```

*   **例如**：

    ```cs
    #define TESTING
    ```

    在这里，`TESTING`是一个符号。

* * *

## `#undef`指令

*   `#undef`指令允许我们取消定义符号。
*   与`#if`伪指令一起使用时，未定义的符号将计算为`false`。
*   **语法**：

    ```cs
    #undef SYMBOL
    ```

*   例如：

    ```cs
    #undef TESTING
    ```

    在这里，`TESTING`是一个符号。

* * *

## `#if`指令

*   `#if`指令用于测试预处理器表达式。
*   预处理器表达式可以仅由符号组成，也可以由符号的组合以及`&&`（AND），`||`（OR），`!`（NOT）等运算符组成。
*   `#if`指令后跟`#endif`指令。
*   仅当使用`#if`测试的表达式的值为`true`时，才会编译`#if`指令中的代码。
*   **语法**：

    ```cs
    #if preprocessor-expression
    	code to compile<
    #endif
    ```

*   **例如**：

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

### 示例 1：如何使用`#if`指令？

```cs
#define CSHARP

using System;

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

当我们运行程序时，输出将是：

```cs
CSHARP is defined
```

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

* * *

## `#elif`指令

*   `#elif`指令与`#if`指令一起使用，可让我们创建复合条件指令。
*   在测试多个预处理器表达式时使用它。
*   仅当用`#elif`测试的表达式的值为真时，才编译`#elif`指令中的代码。
*   **语法**：

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

*   **例如**：

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

* * *

## `#else`指令

*   `#else`指令与`#if`指令一起使用。
*   如果前面的`#if`和`#elif`指令（如果存在）中的表达式都不为真，则将编译`#else`指令中的代码。
*   **语法**：

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

*   **例如**：

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

* * *

## `#endif`指令

*   `#endif`指令与`#if`指令一起使用以指示`#if`指令的结尾。
*   **语法**：

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

*   **例如**：

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

### 示例 2：如何使用条件指令（`if`，`elif`，`else`，`endif`）？

```cs
#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
		}
	}
}
```

当我们运行程序时，输出将是：

```cs
CSHARP is defined, PYTHON is undefined
```

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

* * *

## `#warning`指令

*   `#warning`指令允许我们从代码中生成用户定义的一级警告。
*   **语法**：

    ```cs
    #warning warning-message
    ```

*   **例如**：

    ```cs
    #warning This is a warning message
    ```

* * *

### 示例 3：如何使用`#warning`指令？

```cs
using System;

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

当我们运行程序时，输出将是：

```cs
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`指令允许我们从代码中生成用户定义的错误。
*   **语法**：

    ```cs
    #error error-message
    ```

*   **例如**：

    ```cs
    #error This is an error message
    ```

### 示例 4：如何使用`#error`指令？

```cs
using System;

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

当我们运行程序时，输出将是：

```cs
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`指令允许我们修改行号和文件名以获取错误和警告。
*   **语法**：

    ```cs
    #line line-number file-name
    ```

*   **例如**：

    ```cs
    #line 50 "fakeprogram.cs"
    ```

### 示例 5：如何使用`#line`指令？

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

当我们运行程序时，输出将是：

```cs
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.cs`在`line 10`生成的。 使用`#line`指令，我们将行号更改为`200`，并将文件名更改为`AnotherProgram.cs`，从而产生了错误。

* * *

## `#region`和`#endregion`指令

*   `#region`指令允许我们创建一个使用 Visual Studio 代码编辑器时可以扩展或折叠的区域。
*   该指令仅用于组织代码。
*   `#region`块不能与`#if`块重叠。 但是，`#region`块可以包含在`#if`块内，并且`#if`块可以与`#region`块重叠。
*   `#endregion`指令指示`#region`块的结尾。
*   **语法**：

    ```cs
    #region region-description
    	codes
    #endregion
    ```

### 示例 6：如何使用`#region`指令？

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

当我们运行程序时，输出将是：

```cs
Hello
Hello
Hello
Hello
Hello
```

* * *

## `#pragma`指令

*   `#pragma`指令用于为编译器提供一些特殊的指令，用于编译该文件所在的文件。
*   该指令可以包括禁用或启用某些警告。
*   C# 支持两条`#pragma`指令：
    *   `#pragma warning`：用于禁用或启用警告
    *   `#pragma checksum`：它生成用于调试的源文件的校验和。
*   **语法**：

    ```cs
    #pragma pragma-name pragma-arguments
    ```

*   **例如**：

    ```cs
    #pragma warning disable
    ```

### 示例 7：如何使用`#pragma`指令？

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

当我们运行程序时，输出将是：

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

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

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

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

要了解有关`#pragma`的更多信息，请访问[`#pragma`（C# 参考）](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-pragma "#pragma reference C#")。