Skip to content

Latest commit

 

History

History
594 lines (423 loc) · 11.6 KB

19.md

File metadata and controls

594 lines (423 loc) · 11.6 KB

C# 预处理器指令

原文: https://www.programiz.com/csharp-programming/preprocessor-directives

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

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

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

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

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

Preprocessor directives in C#

#if

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

#if preprocessor-expression
	code to compile
#endif

#elif

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

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

#else

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

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

#endif

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

#if preprocessor-expression
	code to compile
#endif

#define

用于定义符号

#define SYMBOL

#undef

用于取消定义符号

#undef SYMBOL

#warning

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

#warning warning-message

#error

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

#error error-message

#line

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

#line line-number file-name

#region

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

#region region-description
	codes
#endregion

#endregion

指示区域的结尾

#region region-description
	codes
#endregion

#pragma

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

#pragma pragma-name pragma-arguments

#define指令

  • #define指令允许我们定义符号。

  • #if伪指令一起使用时定义的符号将求值为true

  • 这些符号可用于指定编译条件。

  • 语法

    #define SYMBOL
  • 例如

    #define TESTING

    在这里,TESTING是一个符号。


#undef指令

  • #undef指令允许我们取消定义符号。

  • #if伪指令一起使用时,未定义的符号将计算为false

  • 语法

    #undef SYMBOL
  • 例如:

    #undef TESTING

    在这里,TESTING是一个符号。


#if指令

  • #if指令用于测试预处理器表达式。

  • 预处理器表达式可以仅由符号组成,也可以由符号的组合以及&&(AND),||(OR),!(NOT)等运算符组成。

  • #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测试的表达式的值为真时,才编译#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:如何使用条件指令(ifelifelseendif)?

#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# 参考)