#if(C# 参考)#if (C# Reference)

如果 C# 编译器遇到 #if 指令,最终是 #endif 指令,则仅当定义指定的符号时,它才编译这些指令之间的代码。When the C# compiler encounters an #if directive, followed eventually by an #endif directive, it compiles the code between the directives only if the specified symbol is defined. 与 C 和 C++ 不同,你不能为符号分配数字值。Unlike C and C++, you cannot assign a numeric value to a symbol. C# 中的 #if 语句是布尔值,且仅测试是否已定义该符号。The #if statement in C# is Boolean and only tests whether the symbol has been defined or not. 例如:For example:

#if DEBUG
    Console.WriteLine("Debug version");
#endif

仅可以使用运算符 ==(相等)和 !=(不相等)测试 truefalseYou can use the operators == (equality) and != (inequality) only to test for true or false. True 表示定义该符号。True means the symbol is defined. 语句 #if DEBUG 具有与 #if (DEBUG == true) 相同的含义。The statement #if DEBUG has the same meaning as #if (DEBUG == true). 可以使用运算符 && (and)、|| (or) 和 !You can use the operators && (and), || (or), and ! (not) 评估是否已经定义了多个符号。(not) to evaluate whether multiple symbols have been defined. 还可以用括号对符号和运算符进行分组。You can also group symbols and operators with parentheses.

备注Remarks

#if 以及 #else#elif#endif#define#undef 指令,允许基于是否存在一个或多个符号包括或排除代码。#if, along with the #else, #elif, #endif, #define, and #undef directives, lets you include or exclude code based on the existence of one or more symbols. 这在编译调试版本的代码或编译特定配置的代码时会很有用。This can be useful when compiling code for a debug build or when compiling for a specific configuration.

#if 指令开头的条件指令必须以 #endif 指令显式终止。A conditional directive beginning with a #if directive must explicitly be terminated with a #endif directive.

#define 允许你定义一个符号。#define lets you define a symbol. 然后通过将该符号用作传递给 #if 指令的表达式,该表达式的计算结果为 trueBy then using the symbol as the expression passed to the #if directive, the expression evaluates to true.

还可以通过 -define 编译器选项来定义符号。You can also define a symbol with the -define compiler option. 可以通过 #undef 取消定义符号。You can undefine a symbol with #undef.

使用 -define#define 定义的符号与具有相同名称的变量不冲突。A symbol that you define with -define or with #define doesn't conflict with a variable of the same name. 也就是说,变量名称不应传递给预处理器指令,且符号仅能由预处理器指令评估。That is, a variable name should not be passed to a preprocessor directive, and a symbol can only be evaluated by a preprocessor directive.

使用 #define 创建的符号的作用域是在其中定义它的文件。The scope of a symbol created with #define is the file in which it was defined.

此外,生成系统还会感知表示不同目标框架的预定义预处理器符号。The build system is also aware of predefined preprocessor symbols representing different target frameworks. 在创建可以面向多个.NET 实现或版本的应用程序时,这些符号会很有用。They're useful when creating applications that can target more than one .NET implementation or version.

目标框架Target Frameworks 符号Symbols
.NET Framework.NET Framework NETFRAMEWORK, NET20, NET35, NET40, NET45, NET451, NET452, NET46, NET461, NET462, NET47, NET471, NET472, NET48NETFRAMEWORK, NET20, NET35, NET40, NET45, NET451, NET452, NET46, NET461, NET462, NET47, NET471, NET472, NET48
.NET Standard.NET Standard NETSTANDARD, NETSTANDARD1_0, NETSTANDARD1_1, NETSTANDARD1_2, NETSTANDARD1_3, NETSTANDARD1_4, NETSTANDARD1_5, NETSTANDARD1_6, NETSTANDARD2_0, NETSTANDARD2_1NETSTANDARD, NETSTANDARD1_0, NETSTANDARD1_1, NETSTANDARD1_2, NETSTANDARD1_3, NETSTANDARD1_4, NETSTANDARD1_5, NETSTANDARD1_6, NETSTANDARD2_0, NETSTANDARD2_1
.NET Core.NET Core NETCOREAPP, NETCOREAPP1_0, NETCOREAPP1_1, NETCOREAPP2_0, NETCOREAPP2_1, NETCOREAPP2_2, NETCOREAPP3_0NETCOREAPP, NETCOREAPP1_0, NETCOREAPP1_1, NETCOREAPP2_0, NETCOREAPP2_1, NETCOREAPP2_2, NETCOREAPP3_0

其他预定义符号包括 DEBUG 和 TRACE 常量。Other predefined symbols include the DEBUG and TRACE constants. 你可以使用 #define 替代项目的值集。You can override the values set for the project using #define. 例如,会根据生成配置属性(“调试”或者“发布”模式)自动设置 DEBUG 符号。The DEBUG symbol, for example, is automatically set depending on your build configuration properties ("Debug" or "Release" mode).

示例Examples

下例显示如何在文件上定义 MYTEST 符号,然后测试 MYTEST 和 DEBUG 符号的值。The following example shows you how to define a MYTEST symbol on a file and then test the values of the MYTEST and DEBUG symbols. 此示例的输出取决于是在“调试”还是“发布”配置模式下生成项目。The output of this example depends on whether you built the project on Debug or Release configuration mode.

#define MYTEST
using System;
public class MyClass
{
    static void Main()
    {
#if (DEBUG && !MYTEST)
        Console.WriteLine("DEBUG is defined");
#elif (!DEBUG && MYTEST)
        Console.WriteLine("MYTEST is defined");
#elif (DEBUG && MYTEST)
        Console.WriteLine("DEBUG and MYTEST are defined");  
#else
        Console.WriteLine("DEBUG and MYTEST are not defined");
#endif
    }
}

下例显示如何针对不同的目标框架进行测试,以便在可能时使用较新的 API:The following example shows you how to test for different target frameworks so you can use newer APIs when possible:

public class MyClass
{
    static void Main()
    {
#if NET40
        WebClient _client = new WebClient();
#else
        HttpClient _client = new HttpClient();
#endif
    }
    //...
}

请参阅See also