.NET预处理器指令
.NET预处理器指令
做开发以来很少接触到这部分内容,基本上没有用到,偶尔在一些框架中和一些开源项目中会见到,常常因为只关心实现逻辑忽略了这部分的功能。现在自己有点时间了,还是希望能够完整的对这部分做个了解。
#define和#undef
可以使用 #define 指令或 /define 编译器选项定义符号。
使用 #define 可以定义一个符号,并通过将该符号用作表达式传递给条件编译 (#if) 指令,使该表达式的计算结果为 true。
符号可用于指定编译的条件。可以使用 #if 或 #elif 来测试符号。还可以使用 conditional 属性执行条件编译。
可以定义符号,但是无法对符号赋值。#define 指令必须在使用任何也不是指令的指令之前出现在文件中。
用 #define 创建的符号的范围是在其中定义该符号的文件。
// 定义一个符号
#define DEBUG
#undef 使您可以取消符号的定义,以便通过将该符号用作 #if 指令中的表达式,使表达式的计算结果为 false。
// 取消定义符号
#undef DEBUG
// preprocessor_undef.cs
// compile with: /d:DEBUG
#undef DEBUG
using System;
class MyClass
{
static void Main()
{
#if DEBUG
Console.WriteLine("DEBUG is defined");
#else
Console.WriteLine("DEBUG is not defined");
#endif
}
} // 输入:DEBUG is not defined
#if、#elif、#else和#endif
条件编译指令用来根据条件将部分代码段包括进来或排除在外。
#if 使您可以开始条件指令,测试一个或多个符号以查看它们是否计算为 true。如果它们的计算结果确实为 true,则编译器将计算位于 #if 与最近的 #endif 指令之间的所有代码。
可以使用运算符 ==(相等)、!=(不相等)、&&(与)及 ||(或)来计算多个符号。还可以用括号将符号和运算符分组。
以 #if 指令开始的条件指令必须用 #endif 指令显式终止。
// preprocessor_if.cs #define DEBUG
#define VC_V7 using System; public class MyClass
{
static void Main()
{
#if (DEBUG && !VC_V7)
Console.WriteLine("DEBUG is defined");
#elif (!DEBUG && VC_V7)
Console.WriteLine("VC_V7 is defined");
#elif (DEBUG && VC_V7)
Console.WriteLine("DEBUG and VC_V7 are defined");
#else
Console.WriteLine("DEBUG and VC_V7 are not defined");
#endif
}
} // 输出:DEBUG and VC_V7 are defined
Conditional Attribute
[Conditional("DEBUG")]属性作用在方法上,并指定一个预处理符号。如果预处理符号被定义了(计算结果为true),则能正常调用该方法;否则省略对该方法的调用。
class Debug
{
static void Main(string[] args)
{ Print1();
Print2();
Print3(); Console.ReadLine();
} [Conditional("DEBUG")]
static void Print1()
{
Console.WriteLine("Print1");
} // 定义了debug或者trace后才执行
// 或者的关系
[Conditional("DEBUG"), Conditional("Trace")]
static void Print2()
{
Console.WriteLine("Print2");
} // 只有定义了Debug和Trace后才会执行此方法
[Conditional("DEBUGAndTrace")]
static void Print3()
{
Console.WriteLine("Print3");
}
}
#warning和#error
#warning 使您得以从代码的特定位置生成一级警告。#error 使您可以从代码中的特定位置生成错误。
#warning 和#error 通常用在条件指令中。
// preprocessor_warning.cs
// CS1030 expected #define DEBUG class MainClass
{
static void Main()
{
#if DEBUG
#warning DEBUG is defined
#endif
}
}
#region和#endregion
#region 使您可以在使用 Visual Studio 代码编辑器的大纲显示功能时指定可展开或折叠的代码块。
#region 块必须以 #endregion 指令终止。
#region MyClass definition
public class MyClass
{
static void Main()
{
}
}
#endregion
#line
#line 使您可以修改编译器的行号以及(可选)错误和警告的文件名输出。下面的示例说明如何报告与行号关联的两个警告。#line 200 指令强迫行号为 200(尽管默认值为 #7)。另一行 (#9) 作为默认 #line 指令的结果跟在通常序列后。
class MainClass
{ static void Main()
{
#line 200
int i; // CS0168 on line 200
#line default
char c; // CS0168 on line 9
}
}
#line hidden 指令对调试器隐藏若干连续的行,这样当开发人员在逐句通过代码时,将会跳过 #line hidden 和下一个 #line 指令(假定它不是另一个 #line hidden 指令)之间的所有行。
#line hidden 指令不会影响错误报告中的文件名或行号。
#line filename 指令指定您希望出现在编译器输出中的文件名。默认情况下,使用源代码文件的实际名称。文件名必须括在双引号 ("") 中。
下面的示例说明调试器如何忽略代码中的隐藏行。运行此示例时,它将显示三行文本。但是,当设置如示例所示的断点并按 F10 键逐句通过代码时,您将看到调试器忽略了隐藏行。还请注意,即使在隐藏行上设置断点,调试器仍会忽略它。
// preprocessor_linehidden.cs
using System;
class MainClass
{
static void Main()
{
Console.WriteLine("Normal line #1."); // Set break point here.
#line hidden
Console.WriteLine("Hidden line.");
#line default
Console.WriteLine("Normal line #2.");
}
}
#pragma、#pragma warning和#pragma checksum
#pragma 用于给编辑器提供特殊的指令,说明如何编译包含杂注的文件。
#pragma pragma-name pragma-arguments
参数:
pragma-name:可识别杂注的名称。
pragma-arguments:杂注特定的参数。
#pragma warning 可用于启用或禁用某些警告。
#pragma warning disable warning-list
#pragma warning restore warning-list
参数:
warning-list
警告编号的逗号分隔列表。只输入数字,不包括前缀 "CS"。
当没有指定警告编号时,disable 禁用所有警告,而 restore 启用所有警告。
// pragma_warning.cs
using System; #pragma warning disable 414, 3021
[CLSCompliant(false)]
public class C
{
int i = ;
static void Main()
{
}
}
#pragma warning restore 3021
[CLSCompliant(false)] // CS3021
public class D
{
int i = ;
public static void F()
{
}
}
#pragma checksum 可用于生成源文件的校验和,以帮助调试 ASP.NET 页。
Visual Studio 调试器使用校验和来确保找到的总是正确的源。编译器计算源文件的校验和,然后将输出发出到程序数据库 (PDB) 文件。最后,调试器使用 PDB 来比较它为源文件计算的校验和。
此解决方案不适用于 ASP.NET 项目,因为算出的是生成的源文件而不是 .aspx 文件的校验和。为解决此问题,#pragma checksum 为 ASP.NET 页提供了校验和支持。
在 Visual C# 中创建 ASP.NET 项目时,生成的源文件包含 .aspx 文件(从该文件生成源文件)的校验和。然后,编译器将此信息写入 PDB 文件。
如果编译器在该文件中没有遇到 #pragma checksum 指令,它将计算校验和,然后将算出的值写入 PDB 文件。
#pragma checksum "filename" "{guid}" "checksum bytes"
参数:
"filename"
要求监视更改或更新的文件的名称。
"{guid}"
文件的全局唯一标识符 (GUID)。
"checksum_bytes"
十六进制数的字符串,表示校验和的字节。必须是偶数位的十六进制数。奇数位的数字会导致编译时警告,从而使指令被忽略。
.NET预处理器指令的更多相关文章
- C#预处理器指令 ,你造吗??? (●'◡'●)
什么是c#预处理指令?? 用于在 C# 源代码中嵌入的编译器命令. C#预处理器指令有哪些?? ↓↓↓这些就是预处理器指令啦 下面我们一一道来(●'◡'●) 1.#if ,#elif,#else,en ...
- C#预处理器指令
在C#中有许多名为“预处理指令”的命令,这些命令从来不会转化为可执行代码中的命令,但会影响编译过程的各个方面.例如,使用预处理器指令可以禁止编译器编译代码的某一部分.如果计划发布两个版本的代码,即基本 ...
- 一些C#预处理器指令
像C语言一样,C#有一些预处理器指令的命令.例如,#if#end if,#define等,所谓这些命令是指不会转化为可执行代码中的一些命令,只是在编译的过程中起作用.下面简要介绍一下:1 .#defi ...
- C#中的预处理器指令详解
这篇文章主要介绍了C#中的预处理器指令详解,本文讲解了#define 和 #undef.#if.#elif.#else和#endif.#warning和#error.#region和#endregio ...
- C#中的预处理器指令
C#中有许多名为“预处理器指令”的命令.这些命令从来不会转化为可执行代码中的命令,但会影响编译过程的各个方面. 例如,使用预处理器指令可以禁止编译器编译代码的某一部分.如果计划发布两个版本的代码,即基 ...
- C#变量、常量、枚举、预处理器指令知多少
一.变量 C#共有其中变量类型有:静态变量.实类变量.数组元素.数值参数.引用参数.输出参数和局部变量 先定义一个简单的类来说明,如下: public class VariableDefine { p ...
- [No0000FC]C# 预处理器指令
预处理器指令指导编译器在实际编译开始之前对信息进行预处理. 所有的预处理器指令都是以 # 开始.且在一行上,只有空白字符可以出现在预处理器指令之前.预处理器指令不是语句,所以它们不以分号(;)结束. ...
- C#预处理器指令【转】
本文转载自:http://www.cnblogs.com/miffylf/p/4005223.html C#有许多名为预处理器指令的命令.这些命令从来不会转化为可执行代码中的命令,但会影响编译过程的各 ...
- 雷林鹏分享:C# 预处理器指令
C# 预处理器指令 预处理器指令指导编译器在实际编译开始之前对信息进行预处理. 所有的预处理器指令都是以 # 开始.且在一行上,只有空白字符可以出现在预处理器指令之前.预处理器指令不是语句,所以它们不 ...
- c#常用的预处理器指令
预处理器指令指导编译器在实际编译开始之前对信息进行预处理.所有的预处理器指令都是以 # 开始. #define 预处理器指令创建符号常量.#define 允许您定义一个符号,这样,通过使用符号作为传递 ...
随机推荐
- SpringCloud---服务容错保护---Spring Cloud Hystrix
1.概述 1.1 在分布式架构中,存在着许多的服务单元,若一个单元出现故障,很容易因依赖关系引发故障的蔓延,最终导致整个系统的瘫痪: 为了解决这样的问题,产生了断路器等服务保护机制: 1.2 分布式架 ...
- D3.js绘制平行坐标图
参照:https://syntagmatic.github.io/parallel-coordinates/ 和 https://github.com/syntagmatic/parallel-coo ...
- linux CentOS中文输入法安装及设置
摘自百度空间,不错,一次搞定! centos 6.3用yum安装中文输入法 1.需要root权限,所以要用root登录 ,或su root 2.yum install "@Chinese S ...
- 【OpenCV-Python】-图像阀值
参考:Opencv官方教程 1.简单阀值 cv2.threshold , cv2.adaptiveThreshold当像素值高于阀值时,我们给这个像素赋予一个新值(可能是白色),否则我们给它赋予另外一 ...
- Asp.net MVC中repository和service的区别
在Asp.net MVC controller的底层,常常有提到repository和service layer, 好像都是逻辑相关的层,那么它们到底是什么区别呢? 简单的说: repository就 ...
- sencha touch dataview 中添加 button 等复杂布局并添加监听事件
config 中的属性默认都会自动生成 getter setter applier updater 四个方法. applier 在调用 setter 时被调用, updater 在属性值 ...
- Light Table 编辑器修改字体 更新
view->command->use.behaviors 加上这一句 (:lt.objs.style/font-settings "Inconsolata" 14 1 ...
- 虚拟机下linux 的root密码忘记怎么修改(转)
1.开机时任意按一个方向键,进入界面,选择linux系统,按e键进入 2.然后用上下键选择kerner(内核)那一行,按e键进入编辑界面,编辑界面最后一行显示如下:(grub edit> ker ...
- 万物智联,腾讯云 IoT 边缘计算揭秘——云+未来峰会开发者专场回顾
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 背景:现在是万物互联的时代,智能穿戴设备,智能家居,无人商业,改变了我们的生活方式.预计到2021年,全球物联网设数将达到150亿,超过手机 ...
- Linux学习笔记之(1)~Linux有趣的历史概览
献给知道mono,了解Jexus,对.net混搭技术感兴趣的朋友. 1965年,Bell.MIT和GE公司发起Multics计划,目标是实现一个操作系统可以让大型主机实现连接三百个终端的目标.(那个时 ...