预处理指令

这些指令/命令不会转换为可执行代码,但会影响编译过程的各个方面;列如,可以让编译器不编译某一部分代码等。

C#中主要的预处理指令

#define和#undef

#define指令定义

#define DEBUG

它告诉编译器存在DEBUG这个符号;这个符号不是实际代码的一部分,而只是在编译器编译代码时候可能会根据这个符号做条件编译。

#undef定义:

#undef DEBUG

用来移除定义的符号DEBUG。如果不存在这样的标记,#undef指令则不会生效。同样,用#define再次定义一个同名的标记也不会有任何变化。

注意:

  1. 你需要将#define和#undef指令写在实际业务代码开始之前的位置。
  2. #define本身没有什么用,需要和其他预处理器指令结合使用;比如 #if

#if, #elif, #else和#endif

这些指令告诉编译器是否要编译包含在其中的代码块。例如:

int DoSomeWork(double x)
{
// do something
#if DEBUG
Console.WriteLine($"x is {x}");
#endif
}

这段代码中的Console.Writeline语句,只有在前面用#define指令定义了符号DEBUG后才会在编译的时候,真正被编译到;

如果编译器没发现DEBUG符号,就会在编译的时候忽略这句代码。 

#elif(= else if)和#else指令可以用在#if块中:

#define ENTERPRISE
#define W10
// further on in the file
#if ENTERPRISE
// do something
#if W10
// some code that is only relevant to enterprise
// edition running on W10
#endif
#elif PROFESSIONAL
// do something else
#else
// code for the leaner version
#endif

#if和#elif还支持有限的一些逻辑操作符,你可以用使用!,==,!=和||等。

一个标记如果存在,则认为是true,如果没有定义,就认为是false,因此你也可以这样使用:

#if W10 && (ENTERPRISE==false) // if W10 is defined but ENTERPRISE isn't

#warning和#error

当编译器遇到#warning的时候,会产生警告信息;

当编译器遇到#error的时候,会产生错误信息;

    class Program
{
static void Main(string[] args)
{ #warning this is a warning message which will be shown when compile Console.WriteLine("Hello World!"); #error this is a error message, and will break build
}
}

  编译结果:

Program.cs(10,10): warning CS1030: #warning: 'this is a warning message which will be shown when compile' [/define_warning/define_warning.csproj]
Program.cs(14,8): error CS1029: #error: 'this is a error message, and will break build' [/define_warning/define_warning.csproj]
1 Warning(s)
1 Error(s)

  使用这些指令可以检查#define语句是不是做错了什么事,使用#warning可以提醒要做些事情:

#if DEBUG && RELEASE
#error "You've defined DEBUG and RELEASE simultaneously!"
#endif
#warning "Don't forget to remove this line before the boss tests the code!"
Console.WriteLine("*I love this job.*");

  

#region和#endregion

可以用来标识一段代码,在Visual Studio或其他能够识别的IDE里比较有用。

#region Member Field Declarations
int x;
double d;
Currency balance;
#endregion

  

#line

#line指令可以用来改变编译器输出警告和错误时相应的文件名和行号信息。这个实际中,用的可能会比较少。

主要是在用第三方包的时候,有时候会导致编译器报告的行号或文件名与实际不匹配。

#line可以用于还原这种匹配。

#line 164 "Core.cs" // We happen to know this is line 164 in the file Core.cs,
// before the intermediate package mangles it.
// later on
#line default // restores default line numbering

  

#pragma

#pragma指令可以用来终止或恢复某个指定编号到编译器警告。

与命令行选项不同,#pragma指令可以在类或方法级别实现。

例如:

    class Program
{
static void Main(string[] args)
{
int i = 0;
Console.WriteLine("Hello World!");
}
}

  编译是会有warning:

Program.cs(9,17): warning CS0219: The variable 'i' is assigned but its value is never used [/define_warning/define_warning.csproj]
1 Warning(s)
0 Error(s)  

从warning信息可以看出是warning CS0219,加入#pragma后就不会有warning了。

#pragma warning disable CS0219
public class Program
{
static void Main(string[] args)
{
int i = 0;
Console.WriteLine("Hello World!");
}
}
#pragma warning restore CS0219

 注意:warning的代码是区分大小写的,CS2019要大写,如果写成cs2019则没有用。 

学习资料

C#高级编程(第11版) C# 7 & .NET Core 2.0(.NET开发经典名著)

《刻意练习之C#》-0016- C#预处理器指令的更多相关文章

  1. C#预处理器指令 ,你造吗??? (●'◡'●)

    什么是c#预处理指令?? 用于在 C# 源代码中嵌入的编译器命令. C#预处理器指令有哪些?? ↓↓↓这些就是预处理器指令啦 下面我们一一道来(●'◡'●) 1.#if ,#elif,#else,en ...

  2. C#预处理器指令

    在C#中有许多名为“预处理指令”的命令,这些命令从来不会转化为可执行代码中的命令,但会影响编译过程的各个方面.例如,使用预处理器指令可以禁止编译器编译代码的某一部分.如果计划发布两个版本的代码,即基本 ...

  3. 一些C#预处理器指令

    像C语言一样,C#有一些预处理器指令的命令.例如,#if#end if,#define等,所谓这些命令是指不会转化为可执行代码中的一些命令,只是在编译的过程中起作用.下面简要介绍一下:1 .#defi ...

  4. C#中的预处理器指令详解

    这篇文章主要介绍了C#中的预处理器指令详解,本文讲解了#define 和 #undef.#if.#elif.#else和#endif.#warning和#error.#region和#endregio ...

  5. C#中的预处理器指令

    C#中有许多名为“预处理器指令”的命令.这些命令从来不会转化为可执行代码中的命令,但会影响编译过程的各个方面. 例如,使用预处理器指令可以禁止编译器编译代码的某一部分.如果计划发布两个版本的代码,即基 ...

  6. C#变量、常量、枚举、预处理器指令知多少

    一.变量 C#共有其中变量类型有:静态变量.实类变量.数组元素.数值参数.引用参数.输出参数和局部变量 先定义一个简单的类来说明,如下: public class VariableDefine { p ...

  7. [No0000FC]C# 预处理器指令

    预处理器指令指导编译器在实际编译开始之前对信息进行预处理. 所有的预处理器指令都是以 # 开始.且在一行上,只有空白字符可以出现在预处理器指令之前.预处理器指令不是语句,所以它们不以分号(;)结束. ...

  8. C#预处理器指令【转】

    本文转载自:http://www.cnblogs.com/miffylf/p/4005223.html C#有许多名为预处理器指令的命令.这些命令从来不会转化为可执行代码中的命令,但会影响编译过程的各 ...

  9. 雷林鹏分享:C# 预处理器指令

    C# 预处理器指令 预处理器指令指导编译器在实际编译开始之前对信息进行预处理. 所有的预处理器指令都是以 # 开始.且在一行上,只有空白字符可以出现在预处理器指令之前.预处理器指令不是语句,所以它们不 ...

随机推荐

  1. Django认证系统之自定义认证表

    models.py from django.db import models from django.contrib.auth.models import AbstractUser class Use ...

  2. 《机器学习_07_02_svm_软间隔支持向量机》

    一.简介 上一节介绍了硬间隔支持向量机,它可以在严格线性可分的数据集上工作的很好,但对于非严格线性可分的情况往往就表现很差了,比如: import numpy as np import matplot ...

  3. Jmeter(二) - 从入门到精通 - 创建测试计划(Test Plan)(详解教程)

    1.简介 上一篇中宏哥已经教你把JMeter的测试环境搭建起来了,那么这一篇我们就将JMeter启动起来,一睹其芳容,首先宏哥给大家介绍一下如何来创建一个测试计划(Test Plan). 2.创建一个 ...

  4. Null passed to a callee that requires a non-null argument

    OC中定义的方法参数默认是不为空的,如果能够为空需要手动指定__nullable ,我想这个警告是提示开发者警惕可能空参数

  5. Kubernetes学习笔记(五):卷

    简介 卷是Pod的一部分,与Pod共享生命周期.它不是独立的Kubernetes对象,因此不能单独创建. 卷提供的存储功能不但可以解决容器重启后数据丢失的问题,还可以使数据在容器间共享. 一些卷的类型 ...

  6. 实用算法系列之RT-Thread链表堆管理器

    [导读] 前文描述了栈的基本概念,本文来聊聊堆是怎么会事儿.RT-Thread 在社区广受欢迎,阅读了其内核代码,实现了堆的管理,代码设计很清晰,可读性很好.故一方面了解RT-Thread内核实现,一 ...

  7. MySql建库操作

    mysql创建数据库 create database db_namedefault character set utf8; db_name为数据库名 查看所有数据库 show databases; 查 ...

  8. oracle 11g 用户名和密码默认区分大小写

    oracle 11g 用户名和密码默认区分大小写,可更改alter system set sec_case_sensitive_logon=false 设置改为不区分大小写.

  9. eatwhatApp开发实战(二)

    上期,我们做了个小app“eatwhat”,接下来每期都会为其添加新的功能.本期,我们为店铺增加添加店铺的功能. 还是先设置个布局: <RelativeLayout android:layout ...

  10. nginx 配置重定向及nginx配置if

    需求:地址 http://testa/inlinePreview/live.html?id=463738305721405440重定向到 http://testb/shares/live.html?n ...