一、预处理指令概述
C#和C、C++语言类似,也有预处理指令,这个预处指令是由C#编译器提供的。预处理指令“告诉”C#编译器在编译代码时,应该编译哪些代码,如何处理指定的错误和警告,并且提供了如何组织你编写的代码,以便提高代码的可读性。预处理指令由#这个符号开头,一行内写完,换行标志着预处理指令的结束。
二、代码组织预处理指令:#region与#endregion
这一个预处理指令用来组织代码结构,这是常用的一个预处理指令,#region和#endregion是成对使用的。通常的用法有,在一个类中将字段、属性、方法分别用#region与#endregion组织起来;另外一种是函数代码块较长,分步实现的,也常用#region和#endregion来组织代码。语句结构:
#region msg
you code……
#endregion
public class TestModel
{
#region 实体成员
/// <summary>
/// 会议室ID号(GUID码)
/// </summary>
[Column("F_ROOMID")]
public string F_RoomId { get; set; }
/// <summary>
/// 会议室编码
/// </summary>
[Column("F_ROOMCODE")]
public string F_RoomCode { get; set; }
/// <summary>
/// 会议室名称
/// </summary>
[Column("F_ROOMNAME")]
public string F_RoomName { get; set; }
/// <summary>
/// 会议室信息描述
/// </summary>
[Column("F_ROOMINFO")]
public string F_RoomInfo { get; set; }
#endregion
#region 扩展操作
/// <summary>
/// 新增调用
/// </summary>
public void Create()
{
this.F_RoomId = Guid.NewGuid().ToString();
this.F_CreateDate = DateTime.Now;
}
/// <summary>
/// 编辑调用
/// </summary>
/// <param name="keyValue"></param>
public void Modify(string keyValue)
{
this.F_RoomId = keyValue;
this.F_CreateDate = DateTime.Now;
}
#endregion
#region 扩展字段
private string Extension { get; set; }
#endregion
}
三、代码编译错误与警告指令:#error和#warning
#error预处理指令会让编译器在编译代码时,提示一条编译错误的信息。
语句结构:#error error_info;
#warning预处理指令则告诉编译器在编译代码时提示一条编译警告的信息。
语句结构:#warning warning_info;
这两条预处理指令通常具有在项目中起到“提示”的作用,比如说,一个多人协同开发的项目,工程师就可以通过这种方式给项目组中的其他工程师提供编程建议等等,给程序添加类似的“提示”信息。
class Program
{
static readonly int A = B * 10;
static readonly int B = 10;
public static void Main(string[] args)
{
#warning 这个变量是用于初始化定时器的
int setinterval = 10;
#error 这种写法是不允许的,请使用其他实现方法
Console.ReadLine();
}
}
在VS中,定义了一个C#变量时,如果没有使用它,编译程序时会提示一个警告:“warning CS0219:变量‘xxx’已被赋值,但从未使用过它的值”。对于这样的警告是不影响程序运行的,只是编译器的一个警告信息。当你不需要的时候,可以“关闭”这一类的警告信息。语句写法是:#pragma warning disable 警告编码。如果需要重新启用警告,则可以用#pragma warning restore 警告编码。
class Program
{
static readonly int A = B * 10;
static readonly int B = 10;
public static void Main(string[] args)
{
#pragma warning disable 219
int setinterval = 10;
#pragma warning restore 219
int a =3;
Console.ReadLine();
}
}
四、#line预处理指令
指定行号同样是为了标记信息,相当于书签吧,个人的理解。语句结构:#line 行号 “msg”
class Program
{
static readonly int A = B * 10;
static readonly int B = 10;
public static void Main(string[] args)
{
#pragma warning disable 219
int setinterval = 10;
#pragma warning restore 219
#line 100 "指定的行号100"
int a =3;
Console.ReadLine();
}
}
五、条件判断预处理指令#if ,#elif,#else,#endif
在C#中提供了#if ,#elif,#else,#endif这些用于选择执行指定代码的预处理指令;C# 编译器遇到最后面跟有 #endif 指令的 #if 指令,则仅当指定的符号已定义时,它才会编译这两个指令之间的代码。语句结构是:
#if 符号
you code……
#elif 符号
you code……
#else
you code……
#endif
语句结构跟C#中的if……else if …… else类似,只是需要在语句块最后添加#endif,表示预处理指令的结束。在项目中,常用的是判断代码是处于DEBUG模式还是RELEASE模式,来执行指定的代码。如下当时DEBUG模式时,执行Console.WriteLine("调试模式");,输出“调试模式”;当时RELEASE模式时,则执行 Console.WriteLine("发布模式");,输出“发布模式”。
class Program
{
static readonly int A = B * 10;
static readonly int B = 10;
public static void Main(string[] args)
{
#if DEBUG
Console.WriteLine("调试模式");
#else
Console.WriteLine("发布模式");
#endif
Console.ReadLine();
}
}
另外,还可以使用其他符号来使用这一项预处理指令。比如:C#经过发展,现在最新的版本是7,高版本的一些个别语法可能在低版本中不支持,这时就可以使用这一个预处理指令来处理。
#if CSHARP2
you code……
#else
you code……
#endif
六、预定义指令#define与#undef
可以通过 #define 编译器选项来定义符号。 可以通过 #undef 取消定义符号。使用 #define 或 #define 定义的符号与具有相同名称的变量不冲突。 也就是说,变量名称不应传递给预处理器指令,且符号仅能由预处理器指令评估。使用 #define 创建的符号的作用域是在其中定义该符号的文件。
#define EXISTS
#define NOEXISTS
#undef NOEXISTS
using System;
namespace secom.framwork.ca
{
class Program
{
static readonly int A = B * 10;
static readonly int B = 10;
public static void Main(string[] args)
{
#if EXISTS
Console.WriteLine("EXISTS");
#elif NOEXISTS
Console.WriteLine("NOEXISTS");
#endif
Console.ReadLine();
}
}
}
输出:EXISTS