C#【中级篇】 C# 预处理器指令
C#【中级篇】 C# 预处理器指令
前言
预处理器指令指导编译器在实际编译开始之前对信息进行预处理。
所有的预处理器指令都是以 # 开始。且在一行上,只有空白字符可以出现在预处理器指令之前。预处理器指令不是语句,所以它们不以分号(;)结束。
-
C# 编译器没有一个单独的预处理器,但是,指令被处理时就像是有一个单独的预处理器一样。
-
在 C# 中,预处理器指令用于在条件编译中起作用。
-
与 C 和 C++ 不同的是,它们不是用来创建宏。一个预处理器指令必须是该行上的唯一指令。
一、C# 预处理器指令列表
下表列出了 C# 中可用的预处理器指令:
二、 #define 预处理器指令
#define 预处理器指令创建符号常量。
#define 允许您定义一个符号,这样,通过使用符号作为传递给 #if 指令的表达式,表达式将返回 true。它的语法如下:
#define symbol
下面的程序说明了这点:
#define PI
using System;
namespace PreprocessorDAppl
{
class Program
{
static void Main(string[] args)
{
#if (PI)
Console.WriteLine("PI is defined");
#else
Console.WriteLine("PI is not defined");
#endif
Console.ReadKey();
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
PI is defined
三、条件指令
您可以使用 #if 指令来创建一个条件指令。条件指令用于测试符号是否为真。如果为真,编译器会执行 #if 和下一个指令之间的代码。
条件指令的语法:
#if symbol [operator symbol]...
其中,symbol 是要测试的符号名称。您也可以使用 true 和 false,或在符号前放置否定运算符。
常见运算符有:
- == (等于)
- != (不等于)
- && (与)
- || (或)
您也可以用括号把符号和运算符进行分组。条件指令用于在调试版本或编译指定配置时编译代码。一个以 #if 指令开始的条件指令,必须显示地以一个 #endif 指令终止。
下面的程序演示了条件指令的用法:
#define DEBUG
#define VC_V10
using System;
public class TestClass
{
public static void Main()
{
#if (DEBUG && !VC_V10)
Console.WriteLine("DEBUG is defined");
#elif (!DEBUG && VC_V10)
Console.WriteLine("VC_V10 is defined");
#elif (DEBUG && VC_V10)
Console.WriteLine("DEBUG and VC_V10 are defined");
#else
Console.WriteLine("DEBUG and VC_V10 are not defined");
#endif
Console.ReadKey();
}
}
当上面的代码被编译和执行时,它会产生下列结果:
DEBUG and VC_V10 are defined
总结
- 理解#define的使用
- 理解#if、#elif、#endif的使用
- 开发中经常用到 #region和#endregion ,可以使代码结构更清晰!
补充
补充1【预处理器指令的用途理解】
在程序调试和运行上有重要的作用。
比如预处理器指令可以禁止编译器编译代码的某一部分,如果计划发布两个版本的代码,即基本版本和有更多功能的企业版本,就可以使用这些预处理器指令来控制。在编译软件的基本版本时,使用预处理器指令还可以禁止编译器编译于额外功能相关的代码。
另外,在编写提供调试信息的代码时,也可以使用预处理器指令进行控制。总的来说和普通的控制语句(if等)功能类似,方便在于预处理器指令包含的未执行部分是不需要编译的。
#define PI
using System;
namespace PreprocessorDAppl
{
class Program
{
static void Main(string[] args)
{
#if (PI)
Console.WriteLine("PI is defined"); //PI不存在,则这条语句不编译
#else
Console.WriteLine("PI is not defined"); //PI存在,则这条语句不编译
#endif
Console.ReadKey();
}
}
}
补充2【其他预处理器指令】
1. #region 和 #endregion【重要!!!开发中常用于“折叠代码”,对代码进行分区】
#region 和 #endregion 指令用于把一段代码标记为有给定名称的一个块,如下所示:
#region Member Field Declarations
int x;
double d;
Currency balance;
#endregion
这看起来似乎没有什么用,它不影响编译过程。这些指令的优点是它们可以被某些编辑器识别,包括 Visual Studio .NET 编辑器。这些编辑器可以使用这些指令使代码在屏幕上更好地布局。
2. #warning 和 #error:【需要了解!】
当编译器遇到它们时,会分别产生警告或错误。
#warning【警告】:如果编译器遇到 #warning 指令,会给用户显示 #warning 指令后面的文本,之后编译继续进行。
#error【错误】:如果编译器遇到 #error 指令,就会给用户显示后面的文本,作为一条编译错误消息,然后会立即退出编译。
使用这两条指令可以检查 #define 语句是不是做错了什么事,使用 #warning 语句可以提醒自己执行某个操作。
#define DEBUG
#define RELEASE
using System;
namespace UserDefinedException
{
class TestTemperature
{
static void Main(string[] args)
{
#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 hate this job.*");
Console.ReadLine();
}
}
}
一定要亲自测试:
以上代码复制到VS中,可以发现:
#error “You’ve defined DEBUG and RELEASE simultaneously!” 下有波浪红线;
#warning “Don’t forget to remove this line before the boss tests the code!” 下有波浪绿线;
特别说明:
- 有error时,编译无法成功;
- 只有warning时,编译可以成功,实际开发中可忽略warning,但最好是没有warning,有的话,说明代码多少有问题,或可以说,代码不太优美!
3. #line【不常用,不理解也行】
#line 指令可以用于改变编译器在警告和错误信息中显示的文件名和行号信息,不常用。
如果编写代码时,在把代码发送给编译器前,要使用某些软件包改变输入的代码,就可以使用这个指令,因为这意味着编译器报告的行号或文件名与文件中的行号或编辑的文件名不匹配。#line指令可以用于还原这种匹配。也可以使用语法#line default把行号还原为默认的行号:
#line 10 "Core.cs" // 在文件的第 10 行
#line default // 恢复默认行号
完整测试Demo代码:
#define DEBUG
#define RELEASE
#line 10 "Core.cs" // 在文件的第 10 行
#line default // 恢复默认行号
using System;
namespace UserDefinedException
{
class TestTemperature
{
static void Main(string[] args)
{
#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 hate this job.*");
Console.ReadLine();
}
}
}
有#line时:【文件名和行号发生变化】
恢复默认行号后:【文件名和行号恢复原始值】
4. #pragma【简单了解】
#pragma 指令可以抑制或还原指定的编译警告。与命令行选项不同,#pragma 指令可以在类或方法级别执行,对抑制警告的内容和抑制的时间进行更精细的控制。如下:
#pragma warning disable 1030 // 取消编号 1030 的警告
#pragma warning restore 1030 // 恢复编号 1030 的警告
完整测试Demo代码:
#define DEBUG
#define RELEASE
#pragma warning disable 1030 // 取消编号 1030 的警告
//#pragma warning restore 1030 // 恢复编号 1030 的警告
using System;
namespace UserDefinedException
{
class TestTemperature
{
static void Main(string[] args)
{
#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 hate this job.*");
Console.ReadLine();
}
}
}
默认有警告:
取消警告:
相关文章
- C#子线程中更新ui-----c# 多线程多文件批量下载
- 《C#高级编程》学习笔记----c#内存管理--栈VS堆
- C#.NET常见问题(FAQ)-程序不包含适合于入口点的静态“Main”方法怎么办
- Java C# C语言中的占位符
- c#时间与时间戳互转13位
- C#设计模式——观察者模式(Observer Pattern)
- C#,Java,C -循环冗余检验:CRC-16-CCITT查表法
- C# 序列化(总)
- C# 格式化string类型的金额
- Atitit.线程 死锁 跑飞 的检测与自动解除 与手动解除死锁 java c# .net php javascript.
- C# Oracle 连接与修改
- C# 运算符重载
- SQL SERVER类型与C#类型对照
- C#捕获Task异常
- C#开发的OpenRA的游戏主界面怎么样创建3
- CSharp(C#)语言_C#中的“预处理指令”
- (一)如何利用C# Roslyn编译器写一个简单的代码提示/错误检查?
- C#开发PACS医学影像处理系统(十九):Dicom影像放大镜
- C# 获得文件的执行路径的方法