C#-#define条件编译

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

1 #define Debug

说明:

1、Debug可以看做是声明的一个变量,但此变量没有真正的值,存在时#if Debug结果为true,否则为false

2、#define单独用没什么意义,一般是和#if或者Conditional特性结合使用;

3、#define必须定义在所有using命名空间前面;

4、DebugDEBUG是不同的,C#区分大小写。

三、#define条件编译实例

方式一、使用#if

 1 #define Dragon
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Diagnostics;
 7
 8 namespace ConditionalCompilation
 9 {
10     class Program
11     {
12         static void Main(string[] args)
13         {
14 #if Dragon
15             Console.WriteLine("Dragon is defined");
16 #else
17             Console.WriteLine("Dragon is not defined");
18 #endif
19             Console.ReadKey();
20         }
21     }
22 }

输出结果如下:

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

方式二、使用Conditional特性

我们可以将一些函数隔离出来,使得它们只有在定义了某些环境变量或者设置了某个值之后才能发挥作用,使用Conditional特性的隔离策略要比#if/#endif不容易出错。

 1 #define Debug
 2 #define Trace
 3 #if (Debug && Trace)
 4 #define DebugAndTrace
 5 #endif
 6 using System;
 7 using System.Collections.Generic;
 8 using System.Linq;
 9 using System.Text;
10 using System.Diagnostics;
11
12 namespace ConditionalCompilation
13 {
14     class Program
15     {
16         static void Main(string[] args)
17         {
18             Print0();
19             Print1();
20             Print2();
21             Print3();
22             Console.ReadKey();
23         }
24
25         [Conditional("DEBUG")]
26         static void Print0()
27         {
28             Console.WriteLine("DEBUG is defined");
29         }
30
31         [Conditional("Debug")]
32         static void Print1()
33         {
34             Console.WriteLine("Debug is defined");
35         }
36
37         //定义了Debug或者Trace后才会执行此方法
38         //或者的关系
39         [Conditional("Debug"), Conditional("Trace")]
40         static void Print2()
41         {
42             Console.WriteLine("Debug or Trace is defined");
43         }
44
45         //只有定义了Debug和Trace后才会执行此方法
46         //并且的关系
47         [Conditional("DebugAndTrace")]
48         static void Print3()
49         {
50             Console.WriteLine("Debug and Trace is defined");
51         }
52     }
53 }

输出结果如下:

说明:

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间接来完成,如示例代码中的组合操作

1 #if (Debug && Trace)
2 #define DebugAndTrace
3 #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)。

参考链接①:http://www.studyofnet.com/news/1240.html

参考链接②:http://blog.csdn.net/teng_s2000/article/details/5510420

参考链接③:https://msdn.microsoft.com/zh-cn/library/system.diagnostics.conditionalattribute.aspx

时间: 2024-10-09 14:46:16

C#-#define条件编译的相关文章

c#编程中创建全局#define - 条件编译符号

项目-属性-生成-条件编译符号 而不必每次都在类前面#define了. c#编程中创建全局#define - 条件编译符号,布布扣,bubuko.com

C/C++预处理指令#define,条件编译#ifdefine

本文主要记录了C/C++预处理指令,常见的预处理指令如下: #空指令,无任何效果 #include包含一个源代码文件 #define定义宏 #undef取消已定义的宏 #if如果给定条件为真,则编译下面代码 #ifdef如果宏已经定义,则编译下面代码 #ifndef如果宏没有定义,则编译下面代码 #elif如果前面的#if给定条件不为真,当前条件为真,则编译下面代码 #endif结束一个#if--#else条件编译块 #error停止编译并显示错误信息 条件编译命令最常见的形式为: #ifdef

#define用法详解

1.#define 的作用 在C或C++语言源程序中允许用一个标识符来表示一个字符串,称为“宏”.被定义为“宏”的标识符称为“宏名”.在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”.宏定义是由源程序中的宏定义命令完成的.宏代换是由预处理程序自动完成的. 在C或C++语言中,“宏”分为有参数和无参数两种. 2. 无参宏定义 无参宏的宏名后不带参数. 其定义的一般形式为: #define 标识符 字符串 其中的“#”表示这是一条预处理命令.凡是以

c/c++ define用法

define,无参宏定义的一般形式为:#define 标识符 字符串 外文名 define 词条范围 计算机专业用语 无参一般形式 #define 标识符 字符串 带参一般形式 #define 宏名(形参表) 字符串 目录 1参数 2作用 3宏定义优点 4无参宏定义 5带参宏定义 6PHP用法 7例子 ? 例子 1 ? 例子 2 1参数编辑 #define GPEBLT_FUNCNAME(basename) (SCODE (GPE::*)(struct GPEBltParms *))&GPE::

C++编译步骤

编译过程主要分为4个过程 1) 编译预处理   预编译程序完成的工作,可以说成是对源程序的"替换"工作.经过这个过程,生成一个没有宏定义.没有条件编译指令.没有特殊符号的输出文件. 宏定义命令:例如#define 条件编译指令:例如#ifdef 头文件包含指令:例如#include 特殊符号:例如__LINE__,__FILE__ 预处理模块:例如#pragma 2) 编译.优化阶段 通过词法分析.语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价的中间代码或汇编代码. 在C

c++编译过程简介

了解编译过程的益处 c++工程相关的问题 什么是库?静态库和动态库又有什么区别? 头文件起什么作用? 编译过程简介 名词: 编译:把源文件中的源代码翻译成机器语言,保存到目标文件中.如果编译通过,就会把CPP转换成OBJ文件. 编译单元: 每个cpp就是一个编译单元,每个编译单元相互之间是独立且相互不知的.一个编译单元(Translation Unit)是指一个.cpp文件以及这所include的所有.h文件,.h文件里面的代码将会被扩展到包含它的.cpp文件里,然后编译器编译该.cpp文件为一

项目之MFC/VC++疑问巩固1

2019年4月29日22:20:24 1.#define 参考:#define_百度百科在C或C++语言源程序中允许用一个标识符来表示一个字符串,称为"宏".字符串取代宏名.简单代换,字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不作任何检查.如有错误,只能在编译已被宏展开后的源程序时发现.宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起置换. 一般形式为:#define 标识符 字符串 带参宏定义的一般形式为:#define 宏名(形参表) 字符串

JavaWeb(一):Java技术概览

一.Java技术体系 在早期,Java被称为Java开发工具包或JDK,是一门与平台(由一组 必需的API组成)紧密耦合的语言. 从1998年底的1.2版本开始,Java技术栈被分割为下面关键部分: Java是一门包含了严格和强类型语法的语言. Java 2平台标准版本,被称为J2SE,指的是平台以及java.lang和java.io包中包含的类.它是构建Java应用程序的基础. Java虚拟机或JVM是一个可运行编译后Java代码的软件虚拟机.因为被编译过的Java代码只是字节码,JVM将在运

volatile,可变参数,memset,内联函数,宽字符窄字符,国际化,条件编译,预处理命令,define中##和#的区别,文件缓冲,位域

 1.volatile:要求参数修改每次都从内存中的读取.这种情况要比普通运行的变量需要的时间长. #include <stdio.h> #include <stdlib.h> #include <time.h> void main() { time_t start, end; double res = 0; time(&start);  //获取时间,传递给start //volatile强制每次从内存读取 volatile int i; for (i =