C# 条件编译
本文导读:
C#的预处理器指令从来不会转化为可执行代码的命令,但是会影响编译过程的各个方面,常用的预处理器指令有#define、#undef、#if,#elif,#else和#endif等等,下面介绍C#中使用#define进行条件编译的实例。
C#中条件编译指令用于按条件包含或排除源文件中的某些部分。在Visual Studio中,会看到被排除的代码显示为灰色。
一、#define可以用来做什么
1、当计划发布两个版本的代码的时候。即基本版和拥有更多版本的企业版,就可以用到条件编译指令;
2、例如同一个文件给silverlight、wpf、winform等使用,并且还考虑Debug和Release等,有大部分代码是一样的;
3、指定函数和属性是否编译到最终产品中去。
二、#define用法
语法:#define 名称
注意:这里名称取Debug,你也可以取其他名称如Dragon
#define Debug
说明:
1、Debug可以看做是声明的一个变量,但此变量没有真正的值,存在时#if Debug结果为true,否则为false;
2、#define单独用没什么意义,一般是和#if或者Conditional特性结合使用;
3、#define必须定义在所有using命名空间前面;
4、Debug与DEBUG是不同的,C#区分大小写。
三、#define条件编译实例
方式一、使用#if
#define Dragon
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics; namespace ConditionalCompilation
{
class Program
{
static void Main(string[] args)
{
#if Dragon
Console.WriteLine("Dragon is defined");
#else
Console.WriteLine("Dragon is not defined");
#endif
Console.ReadKey();
}
}
}
输出结果如下:

如果注释掉
//#define Dragon
输出结果为:

方式二、使用Conditional特性
我们可以将一些函数隔离出来,使得它们只有在定义了某些环境变量或者设置了某个值之后才能发挥作用,使用Conditional特性的隔离策略要比#if/#endif不容易出错。
#define Debug
#define Trace
#if (Debug && Trace)
#define DebugAndTrace
#endif
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics; namespace ConditionalCompilation
{
class Program
{
static void Main(string[] args)
{
Print0();
Print1();
Print2();
Print3();
Console.ReadKey();
} [Conditional("DEBUG")]
static void Print0()
{
Console.WriteLine("DEBUG is defined");
} [Conditional("Debug")]
static void Print1()
{
Console.WriteLine("Debug is defined");
} //定义了Debug或者Trace后才会执行此方法
//或者的关系
[Conditional("Debug"), Conditional("Trace")]
static void Print2()
{
Console.WriteLine("Debug or Trace is defined");
} //只有定义了Debug和Trace后才会执行此方法
//并且的关系
[Conditional("DebugAndTrace")]
static void Print3()
{
Console.WriteLine("Debug and Trace is defined");
}
}
}
输出结果如下:

说明:
1、代码中没有定义DEBUG,却输出了DEBUG,是因为DEBUG版本,自动定义了DEBUG。“项目——右键——属性——生成选项卡——常规栏”下的定义 DEBUG 常量(U)前面的复选框被选中。当然你可以去掉其选中状态,这样就不会输出DEBUG了。
2、如果Debug和Trace均没有定义,则不会输出Debug or Trace;只有Debug和Trace均定义了,才会输出Debug and Trace。
3、可以给Conditional增加多个属性如示例代码
[Conditional("Debug"), Conditional("Trace")]
不过多个属性之间的关系是或的关系,即“Debug”或者“Trace”任意一个被定义了,那么对应方法就会被执行。
4、如果需要增加多个与的属性,直接用Conditional是无法实现的,需要借助#if/#endif间接来完成,如示例代码中的组合操作
#if (Debug && Trace)
#define DebugAndTrace
#endif
使用Conditional属性的方法受到以下限制:
1、条件方法必须是类声明或结构声明中的方法。如果在接口声明中的方法上指定Conditional属性,将出现编译时错误;
2、条件方法不能是接口方法的实现。否则将发生编译时错误;
3、条件方法必须具有void返回类型;
4、不能用override修饰符标记条件方法。但是,可以用virtual修饰符标记条件方法。此类方法的重写方法隐含为有条件的方法,而且不能用Conditional属性显式标记。
环境变量(或条件编译符号)的设置方法有三:
1)用#define定义以及#undef取消定义,在所有using命名空间前面定义;
2)用编译器命令行选项(例如,/define:DEBUG),在“项目——右键——属性——生成选项卡——常规栏”下的条件编译符号(Y)中设置(如果多个,可以用英文逗号隔开)。DEBUG版本下,系统默认设置了DEBUG和TRACE;
3)用操作系统外壳程序中的环境变量(例如,set DEBUG=1)。
C# 条件编译的更多相关文章
- C#-#define条件编译
本文导读: C#的预处理器指令从来不会转化为可执行代码的命令,但是会影响编译过程的各个方面,常用的预处理器指令有#define.#undef.#if,#elif,#else和#endif等等,下面介绍 ...
- 条件编译#if
1.为什么需要条件编译 客户的需求在不停地发生变化,一会儿需要这个功能,一会儿不需要这个功能.我们可以使用条件编译来方便地裁剪功能. 2.条件编译语句#if 条件编译语句#if的形式是 #if exp ...
- 条件编译#if #ifdef
近期由于一些莫名其妙的原因开始学c++,我觉得我哪天要是挂了也是被自己给折腾死的,算了,反正不是折腾死就是被淘汰,当是没事打发时间了,废话不多说,开始今天的主题. 之前接触的注释就是注释,条件语句就是 ...
- [AIR] as3 之条件编译多平台妙用
http://bbs.9ria.com/thread-418864-1-1.html 一直希望as3 可以支持条件编译,即满足A时编译函数1,满足B时则编译函数2. 最佳百度了之后,发现原来是可以实现 ...
- 认识Visual Studio 条件编译
一开始是在一些源代码中看到这些语法符号,了解到这就是" 条件编译"技术
- C# 条件编译备忘
第一步:配置管理器中新建解决方案配置 第二步:定义条件编译符号: 第三步:在代码中使用自定义的条件编译 #if CustomDebug Console.WriteLine("dsads&qu ...
- Java条件编译
学习过C语言或者C++语言的同学都知道它们支持条件编译,那么今天我们来学习下在Java语言中如何实现条件编译.Java语言本身没有提供条件编译,但是Java编译器对.java文件编译为.class文件 ...
- c#定义全局条件编译符号
在"工程"上单机右键,"属性"--->"生成"--->"条件编译符号"后边的输入框中,输入自定义的条件编译变 ...
- 如何判断平台工具集去做条件编译(VC++目录、预处理器定义、$(PlatformToolsetVersion))
作者:zyl910 从VS2010开始,提供了一个平台工作集(Platform ToolSet)选项用于配制vc编译版本.到了VS2012,更是因为默认平台工具集不支持WindowsXP,导致经常需要 ...
随机推荐
- MySQL主从环境下存储过程,函数,触发器,事件的复制情况
下面,主要是验证在MySQL主从复制环境下,存储过程,函数,触发器,事件的复制情况,这些确实会让人混淆. 首先,创建一张测试表 mysql),age int); Query OK, rows affe ...
- 最好的.NET开源免费ZIP库DotNetZip(.NET组件介绍之三)
在项目开发中,除了对数据的展示更多的就是对文件的相关操作,例如文件的创建和删除,以及文件的压缩和解压.文件压缩的好处有很多,主要就是在文件传输的方面,文件压缩的好处就不需要赘述,因为无论是开发者,还是 ...
- Unity3D框架插件uFrame实践记录(一)
1.概览 uFrame是提供给Unity3D开发者使用的一个框架插件,它本身模仿了MVVM这种架构模式(事实上并不包含Model部分,且多出了Controller部分).因为用于Unity3D,所以它 ...
- 流程表单中js如何清空SheetUser控件数据?
昨天有人问我js怎么清空.我试了试,发现简单的赋给他空值,并没有用.只能给他赋一个真实存在的值才有用.于是跟踪了一下他的删除按钮. 效果如下 使用场景:可以根据字段的不同类别变更人员. js代码如下, ...
- 直播推流端弱网优化策略 | 直播 SDK 性能优化实践
弱网优化的场景 网络直播行业经过一年多的快速发展,衍生出了各种各样的玩法.最早的网络直播是主播坐在 PC 前,安装好专业的直播设备(如摄像头和麦克风),然后才能开始直播.后来随着手机性能的提升和直播技 ...
- QDEZ集训笔记【更新中】
这是一个绝妙的比喻,如果青岛二中的台阶上每级站一只平度一中的猫,差不多站满了吧 自己的理解 [2016-12-31] [主席树] http://www.cnblogs.com/candy99/p/61 ...
- 一步步开发自己的博客 .NET版(9、从model first替换成code first 问题记录)
为什么要改用code first 用过code first的基本上都不会再想用回model first或是db first(谁用谁知道).不要问我为什么不一开始就直接使用code first,因为那个 ...
- AutoMapper(七)
返回总目录 Null值替换 如果源类型的成员链上的属性值为Null,Null值替换允许提供一个可替换的值.下面有两个类Person和PersonInfo类,都有一个属性Title(头衔),从Perso ...
- ENode简介与各种教学视频资源汇总(要进群这篇文章必看)
ENode是什么 ENode是一个.NET平台开源的应用开发框架,为开发人员提供了一套完整的基于DDD+CQRS+ES+(in-memory)+EDA架构风格的解决方案. ENode的特色是什么 解决 ...
- 当前端也拥有 Server 的能力
今天看了不少文章,比较感兴趣的是 Cache API.它是浏览器 Request/Response 的缓存管理工具,其使用风格和运用场景让我瞬间联想到了 ServiceWorker 和 Fetch A ...