当前位置: 首页 > 编程笔记 >

C# #define条件编译详解

陆博易
2023-03-14
本文向大家介绍C# #define条件编译详解,包括了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

#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后才会html" target="_blank">执行此方法
    //或者的关系
    [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)。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 主要内容:#if 的用法,#ifdef 的用法,#ifndef 的用法,三者之间的区别假如现在要开发一个C语言程序,让它输出红色的文字,并且要求跨平台,在 Windows 和 Linux 下都能运行,怎么办呢? 这个程序的难点在于,不同平台下控制文字颜色的代码不一样,我们必须要能够识别出不同的平台。 Windows 有专有的宏 ,Linux 有专有的宏 ,以现有的知识,我们很容易就想到了 if else,请看下面的代码: 但这段代码是错误的,在 Windows 下提示 __linu

  • 本文向大家介绍C/C++中的typedef和#define详解,包括了C/C++中的typedef和#define详解的使用技巧和注意事项,需要的朋友参考一下 C/C++中的typedef和#define 前言:      在C/C++中,我们平时写程序可能经常会用到typedef关键字和#define宏定义命令,在某些情况下使用它们会达到相同的效果,但是它们是有实质性的区别,一个是C/C++的关

  • 问题内容: 我在Go 1中使用条件编译遇到了麻烦。 这是我的测试代码。关于“ // + build”约束和“ -tags”标志,我有什么误解吗? main1.go main2.go 运行“执行构建”时,我仍然出现编译错误 问题答案: 您必须跟随一个空白行。 在我的简短搜索中,找不到该文件的记录位置/位置。但消息人士明确指出

  • Rust 有一个特殊的属性,#[cfg],它允许你基于一个传递给编译器的标记编译代码。它有两种形式: #[cfg(foo)] # fn foo() {} #[cfg(bar = "baz")] # fn bar() {} 它还有一些帮助选项: #[cfg(any(unix, windows))] # fn foo() {} #[cfg(all(unix, target_pointer_wid

  • 编译器有一个定义符号列表,定义符号可以通过 !define 定义或使用 /D 命令行开关。这些定义符号可以用于条件编译 (通过 !ifdef 定义) 或用于符号替换 (一种格式简单的宏)。若要用它的值替换一个符号,请使用 ${符号} (如果没有定义符号,那么不会产生转换)。这个转换为“先到先得”,这意味着如果你做了: !define 符号1 ${符号2} 当出现该行时,如果定义了“符号2”它将

  • 条件编译在处理机器依赖、调试以及编译阶段设定特定选项时十分有用。不过要小心条件编译。各种控制很容易以一种无法预料的方式结合在一起。如果使用#ifdef判断机器依赖,请确保当没有机器类型适配时,返回一个错误,而不是使用默认机器类型(使用#error并缩进一级,这样它可以一些老旧的编译器下工作)。如果你#ifdef优化选项,默认情况下应该是一个未经优化的代码,而不是一个不兼容的程序。确保测试的是未经优