C#预处理指令和Conditional特性

目录

 

1.C#预处理指令

2.预处理指令的基本规则

3. #define和#undef指令

4. 条件编译

5. 条件编译代码示例

6. conditional特性


1.C#预处理指令

我们写的代码制定了程序的定义,预处理指令指示编译器如何处理代码。例如,在某些情况下,我们希望编译器忽略一部分代码,在某些情况下我们又希望这些代码被编译,预处理指令则能让我们轻松实现这样的功能。

学过C++和C语言的都知道,C和C++中有实际的预处理阶段,此时预处理程序便利源代码并且为之后的编译阶段准备文本输出流,在C#中没有实际的预处理程序。

2.预处理指令的基本规则

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

3. #define和#undef指令

编译符号是只有两种可能状态的标识符,要么被定义,要么未被定义,编译符号有如下特性:

  • 它可以是除了true或false意外的任何标识符,包括C#关键字,以及在C#代码中声明的标识符。
  • 它没有值。与C和C++不同,它不表示字符串。
  • #define指令声明一个编译符号;
  • #undef指令取消定义一个编译符号。
  • #define和#undef指令只能用在源文件的第一行,也就是C#任何代码的前面,在C#代码开始后,#define和#undef指令就不能再使用。
  • 编译符号的范围被限制与单个源文件,只要编译符号再任何C#代码之前,重复定义编译符号页视允许的。

4. 条件编译

条件编译允许我们更具谬个编译符号是否被定义标注一段代码被编译或跳过。有4个指令可以英阿历指定条件编译:

  • #if
  • #else
  • elif
  • #endif

其中,条件时一个返回true或false的简单状态。条件可以由单个编译符号,符号表达式或操作符组成。子条件可以使用圆括号分组。

上面四个条件编译指令和我们普通的条件判断指令使用方法类似,if、elif、else。

#if !DemoVersion
    ...
#endif


#if (Lefthandle && OemVersion)||胜利
   ...
#endif


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

5. 条件编译代码示例

#define Dragon
//#undef Dragon

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Learn_Preprcocess_directive
{
    class Program
    {
        static void Main(string[] args)
        {
#if Dragon
            Console.WriteLine("Dragon is defined.");
#else
            Console.WriteLine("Dragon is not defined.");
#endif
        }
    }
}

在VS中,else中的语句是灰色的,所以运行的结果是:Dragon is defined.   如果将第二行的双斜杠删除,那么就会执行#else中的代码。

6. 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.Threading.Tasks;

using System.Diagnostics;
namespace Learn_Preprcocess_directive
{
    class Program
    {
        static void Main(string[] args)
        {
            Print_1();
            Print_2();
            Print_3();
            Print_4();
        }
        [Conditional("Debug")]
        static void Print_1()
        {
            Console.WriteLine("Debug is defined");
        }

        [Conditional("DEBUG")]
        static void Print_2()
        {
            Console.WriteLine("DEBUG is defined");

        }
        //只有定义了Debug或者Tarce后才会执行此方法
        [Conditional("Debug"),Conditional("Trace")]
        static void Print_3()
        {
            Console.WriteLine("Debug or Trace is defined");
        }
        //只有定义了Debug和Trace后才会执行此方法
        static void Print_4()
        {
            Console.WriteLine("Debug and Trace is defined");
        }
    }
}

运行结果如下:

 奇怪的事情发生了,我们明明没有定义DEBUG,为什么又输出了DEBUG,这是因为在DEBUG版本,自动定义了DEBUG。我们将编译模式改成release,然后在运行,你就会发现回复正常了。

使用Conditional属性的方法受到以下限制:

  1. 条件方法必须是类声明或结构声明中的方法。如果在接口声明中的方法指定Conditional属性,将出现编译的错误
  2. 条件方法不能是接口方法的实现。否则将发生编译错误
  3. 条件方法必须具有void返回类型
  4. 不能用override修饰符标记方法。但是virtual修饰符标记条件方法。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值