[笔记]读.Net 2.0面向对像揭密--条件编译

条件编译

条件编译属于编译预处理的范畴,与c++不同,c#没有独立的预处理器。C#中的预处理指令仅仅用来与c保持一致,而不是编译器开始编译代码之前得一个单独的处理步骤,他是作为词法分析的一部分来执行的。

Msdn关于条件编译的说明:

可以使用条件编译选择特定的代码节进行编译,而排除其他代码节。例如,可能需要编写调试语句来比较同一编程任务的不同方法的速度,或者可能需要本地化用于多种语言的应用程序。条件编译语句被设计为在编译时(而不是在运行时)运行。

image

在VS2010中黓认已定义DEBUG & TRACE

 

条件编译指令

条件编译指令有以下四种:#if、#elif、#else、#endif

这些条件编译指令用来有条件的将部分程序段包括进来或排除在外。他们和c#中的if语句有类似的作用。

条件编译符号有两种可能的状态:已定义的或未定义的。在源文件词法处理开始时,条件编译符号除非已由外部机制(如命令行编译器选项)显式定义,否则是未定义的。

他们在程序中的出现的先后顺序必须是这样:

一条#if语句(必须有)

零或多条#elif语句

零或一条#else语句

一条#endif语句(必须有)

#define或#undef必须定义在所有using 命名空间前面.#define类型为布尔值的真,#undef为布尔值的假.

C#为此提出了一种更好的选择:Conditional特性。使用Conditional特性,我们可以将一些函数隔离出来,使得它们只有在定义了某些环境变量或者设置了某个值之后才能发挥作用。Conditional特性最常用的地方就是将代码改编为调试语句。.NET框架已经为此提供了相关的功能支持。

DEMO测试

Demo1:测试DEBUG,在不同编译模式下的结果

#define DEBUG //定义DEBUG
using System;
using System.Collections.Generic;
using System.Text;

namespace Demo
{
    class Program
    {
        #if DEBUG
            static void PrintInfo()
            {
                System.Console.WriteLine("Debug Version");
            }
        #else
            static void PrintInfo()
            {
                System.Console.WriteLine("Released Version");
            }
        #endif

        static void Main(string[] args)
        {

            #if DEBUG   //以下代码被编译到Debug版本中
                System.Console.WriteLine("Debug版本");
            #else      //以下代码被编译到Release版本中
                System.Console.WriteLine("Released版本");
            #endif
            
            PrintInfo(); //根据条件编译符号确定输出是英语还是汉语

            //以下代码所有Debug与Release都有
            System.Console.ReadKey();
        }
    }
}

不论是在Debug / Release模式下得到的结果都如下:

image

结论:

定义了DEBUG后,无论使用Debug / Release 模式,始终 #if DEBUG为True.

这里有一点在测试的过程中发现的,在切换不同编译模式时,其实VS会自动将不执行的语句颜色变成灰色,如下图所示:

 image

Demo2,接下我再测试一下去掉#define DEBUG,在Debug / Release模式下结果如何

//#define DEBUG //定义DEBUG
using System;
using System.Collections.Generic;
using System.Text;

namespace Demo
{
    class Program
    {
        #if DEBUG
            static void PrintInfo()
            {
                System.Console.WriteLine("Debug Version");
            }
        #else
            static void PrintInfo()
            {
                System.Console.WriteLine("Released Version");
            }
        #endif

        static void Main(string[] args)
        {

            #if DEBUG   //以下代码被编译到Debug版本中
                System.Console.WriteLine("Debug版本");
            #else      //以下代码被编译到Release版本中
                System.Console.WriteLine("Released版本");
            #endif
            
            PrintInfo(); //根据条件编译符号确定输出是英语还是汉语

            //以下代码所有Debug与Release都有
            System.Console.ReadKey();
        }
    }
}

得到的结果分别如下:

Debug模式下

image

Released模式下

image

结论:

此时虽然我们在前都没有定义条件编译的指令,可#if DEBUG在Debug模式下自然为True,所以此时会得到的是"Released版本"的结果,而Release下为False,相反得到的是"Debug版本"结果.

同理在测试TRACE时結果和DEBUG一致,這里不明白的是DEBUG和TRACE的區別是什麼?

Demo3,测试自定义条件

#define English
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace CSCompile
{
    class Program
    {
#if English
        static void PrintInfo()
        {
             System.Console.WriteLine("English Version");
        }
#else
        static void PrintInfo()
        {
            System.Console.WriteLine("中文版");
        }
#endif

        static void Main(string[] args)
        {
            PrintInfo(); //根据条件编译符号确定输出是英语还是汉语

            //以下代码所有Debug与Release都有
            System.Console.ReadKey();
        }
    }
}
结论:

不论是Debug模式 / Released模式下,当有定义"English"时都会得到"English Version",同样如果前面没有定义"English"时只都只会得到'中文版"结果.

 

Demo 4,Conditional测试

#define English
#define DEBUG
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace CSCompile
{
    class Program
    {
#if English
        static void PrintInfo()
        {
             System.Console.WriteLine("English Version");
        }
#else
        static void PrintInfo()
        {
            System.Console.WriteLine("中文版");
        }
#endif
        [Conditional("DEBUG")]
        static void Print()
        {
            System.Console.WriteLine("Conditional");
        }

        static void Main(string[] args)
        {
            PrintInfo(); //根据条件编译符号确定输出是英语还是汉语
            Print();

            //以下代码所有Debug与Release都有
            System.Console.ReadKey();
        }
    }
}
结论:

和前面DEBUG测试一致,只是Conditional可以更方便的应用在函数上面.

 

其它说明

1.在引入System.Diagnostics命名空间后,我们可以对Debug / Trace 进行相应的代码编写,详见参考资料中第5点.

 

参考资料

1.c# 条件编译 #define #if #endif

2.C#中的预处理指令,你用了多少?

3.C#.NET学习笔记5---C#中的条件编译

4.c#条件编译

5.从Trace和Debug来看条件编译(Conditional Compilation)

posted @ 2011-09-07 11:56  AthrunSoft  阅读(295)  评论(0)    收藏  举报