• 友链

  • 首页

  • 文章归档
h u a n b l o g
h u a n b l o g

欢

HI,Friend

04月
16
C#

预处理指令

发表于 2022-04-16 • 字数统计 4977 • 被 1,660 人看爆

概念

指示编译器如何处理源代码

规则

  • 预处理指令必须和C#代码在不同的行。
  • 与C#语句不同,预处理指令不需要以分号结尾。包含预处理指令的每一行必须以#字符开始。
    • 在#字符前可以有空格。
    • 在#字符和指令之间可以有空格。
  • 允许行尾注释。
  • 在预处理指令所在的行不允许分隔符注释。

例

#define PremiumVersion      //正确  没有分号
 #define BudgetVersion      //正确 前面空格
# define MediumVersion      //正确 中间空格

#define PremiumVersion      /* 注释 */  //错误 不允许分隔符注释(/**/)  行注释可以,也就是//

预处理指令

指令含义概要
#define identifier定义编译符
#undef identifier取消定义编译符
#if expression如果表达式是true,编译下面的片段
#elif expression如果表达式是true,编译下面的片段
#else如果之前的#if或#elif表达式是false,编译下面
#endif标记为一个#if结构的结束
#region name标记一段代码的开始,没有编译效果
#endregion name标记一段代码的结束,没有编译效果
#warning message显示编译时的警告消息
#error message显示编译时的错误消息
#line indicator修改在编译器消息中显示的行数
#pragma text指定有关程序上下文的信息

#define和#undef指令

声明和取消定义一个编译符号

规则

  • 它可以是除了true或false以外的任何标识符,包括C#关键字,以及在C#代码中声明的标识符,这两者都是可以的。
  • 它没有值。与C和C++不同,它不表示字符串。
  • #define指令声明一个编译符号;
  • #undef指令取消定义一个编译符号。

例1

#define PremiumVersion
#define EconomyVersion
...
#undef PremiumVersion

#define和#undef指令只能用在源文件的第一行,也就是任何C#代码之前使用。在C#代码开始后,#tdefine和#undef指令就不能再使用。

例2

using System    //C#代码第一行
#define PremiumVersion      //错误

namespace Eagle{
    #define PremiumVersion      //错误
}

编译符号的范围被限制于单个源文件。只要编译符号在任何C#代码之前,重复定义已存在的编译符号也是允许的。

#define AValue
#define BValue

#define AValue      //重复定义

条件编译

根据某个编译符号是否被定义标注一段代码被编译或跳过
  • #if
  • #else
  • #elif
  • endif

条件是一个返回true或false的简单表达式

在#if和#elif指令中使用的条件

参数类型意义运算结果
编译符号使用#define指令(未)定义的标识符True:如果符号已经使用#define指令定义 Fasle:其它
表达式使用符号和操作符!、==、!=、&&、

例

#if !DemoVersion    //表达式
...
#endif

#if (LeftHanded && OemVersion)  //表达式
...
#endif

#if true        //下面代码总会被编译
....
#endif

条件编译结构

#if....#endif结构

#if和#endif指令在条件编译结构中需要配对使用。只要有#if指令,就必须有配对的#endif。

  • 如果#if结构中的条件运算结果为true,随后的代码段就会被编译,否则就会被跳过。
  • 在#if...#else结构中,如果条件运算结果为true,CodeSection1就会被编译,否则,CodeSection2会被编译。

#if Codition
    CodeSection1
#elseif
    CodeSection2
#endif

#if..#elif结构

#if Cond1
    CodeSection1
#elif   Cond2
    CodeSection2
#elif   Cond3
    CodeSection3
#endif

  • 如果Cond1运算结果为true,CodeSection1就会被编译,然后就会继续编译#endif之后的代码;
  • 否则,如果cond2运算结果为true,CodeSection2就会被编译,然后会继续编译#endif之后的代码;
  • 直到条件运算结果为true或所有条件都返回false,如果这样,结构中没有任何代码段会被编译,会继续编译#endif之后的代码。

#if..#elif..#else结构

和#if..#elif一样方式。只不过没有条件是true的情况下,会编译#else之后的代码段,然后会继续编译#endif之后的代码。

#if Cond1
    CodeSection1
#elif   Cond2
    CodeSection2
    ....
#else   
    CodeSectionN
#endif

示例

字符串根据定义的编译符号被设置为各种

#define DemoVersionwithoutTimeLimit
    ... 
    const int intExpireLength = 30;
    string strVersionDesc= null;
    int intExpireCount= 0;
    
#if DemoVersionWithTimeLimit
    intExpireCount = intExpirelength;
    strVersionDesc = "This version of Supergame Plus will expire in 30 days";

#elif DemoVersionwithoutTimeLimit
    strVersionDesc = "Demo Version of Supergame Plus";

#elif OEMVersion
    strVersionDesc = "Supergame Plus,distributed under license";

#else
    strVersionDesc = "The original Supergame Plus!!";

#endif
    Console.writeline( strVersionDesc );
    ....

诊断指令

诊断指令产生用户自定义的编译时警告及错误消息。

语法

#warning Message        
#error Message

Message是字符串,无需引号

示例
#error指令在#if结构中,因此只有符合#if指令的条件时才会生成消息。
#warning指令用于提醒程序员回头来清理这段代码。

#define RightHanded
#define LeftHanded

#if RightHanded && LeftHanded
#error Can't build for both RightHanded and LeftHanded
#endif

#waring Remember to come back and clean up this code!

行号指令

功能

  • 改变由编译器警告和错误消息报告的出现行数;
  • 改变被编译源文件的文件名;
  • 对交互式调试器隐藏一些行。

语法

#line integer  //设置下一行值为整数的行的行号
#line "filename"    //设置文件名
#line defaule       //重新保存实际的行号和文件名

#line hidden        //在断点调试器中隐藏代码
#line       //停止在调试器中隐藏代码

#line指令加上一个整数参数会使编译器认为下面代码的行是所设置的行,之后的行数会再这个行数的基础上递增。

要改变外观文件名,可以在双引号内使用文件名作为参数。双引号是必需的。
要返回真实行号和真实文件名,可以使用default参数。
要对交互调试器的断点调试功能隐藏代码段,可以使用hidden作为参数。要停止隐藏,可以使用不带任何参数的指令。到目前为止,这个功能大多用于在ASP.NET和WPF中隐藏编译器生成的代码。

示例

#line 226
    x = y + z;      //编译器将执行第226行
    ...

#line 330 "SourceFile.cs"       //改变报告的行号和文件名
    var1 = var2 + var3;

#line defaule       //重新保存行号和文件名

区域指令

区域指令允许我们标注和有选择性地命名一段代码

特性

  • 被放置在希望标注的代码段之上;
  • 用指令后的可选字符串文本作为其名字;
  • 在之后的代码中必须由#endregion指令终止。

示例
在编辑器隐藏代码区域

#region Constructors
MyClass() {
    ...
}

#endregion

#pragma warning指令

允许我们关闭及重新开启警告消息。

规则

  • 要关闭警告消息,可以使用disable加上逗号分隔的希望关闭的警告数列表的形式。
  • 要重新开启警告消息,可以使用restore加上逗号分隔的希望关闭的警告数列表的形式。

示例


#pragma warning disable 618,414      //要关闭的警告消息
....        //列出的警告消息在这段代码中处于关闭状态

#pragma warning restore 618 //要开启的警告消息
分享到:
特性
异常处理程序
  • 文章目录
  • 站点概览
欢

网红 欢

你能抓到我么?

Email RSS
看爆 Top5
  • mac系统版本与Xcode版本有冲突 4,084次看爆
  • JAVA_HOME环境配置问题 3,734次看爆
  • AssetBundle使用 3,503次看爆
  • VSCode配置C++开发环境 3,260次看爆
  • Lua反射 3,136次看爆

Copyright © 2025 欢 粤ICP备2020105803号-1

由 Halo 强力驱动 · Theme by Sagiri · 站点地图