c#的预编译指令
原始 http://hahha2003.blog.163.com/blog/static/248577920114204133758/我的blog是用开源的BlogEngine来架设的,有的时候为了满足自己的需求及要对源代码做一些修改。在我调试客户端代码的时候,不管是使用Firebug或者是Vs 2008来调试,看到的Javascript代码都是经过动态压缩过了的,这个系统有一个HttpH
原始 http://hahha2003.blog.163.com/blog/static/248577920114204133758/
我的blog是用开源的BlogEngine来架设的,有的时候为了满足自己的需求及要对源代码做一些修改。在我调试客户端代码的时候,不管是使用Firebug或者是Vs 2008来调试,看到的Javascript代码都是经过动态压缩过了的,这个系统有一个HttpHanddle是专门用来处理js文件请求的,在第一次请求的时候会对js代码进行压缩,去掉了注释换行符等不必要的字符,这样可以提高访问的速度,但是对调试非常的不利,相信我们谁都不愿意对着一堆压缩过了的JS代码做调试。于是我想到了C#的预编译指令,再网上搜索整理了一番,做一个总结。
c#的预编译指令
C#预处理器指令是在编译时调用的。预处理器指令(preprocessor directive)告诉C#编译器要编译哪些代码,并指出如何处理特定的错误和警告。C#预处理器指令还可以告诉C#编辑器有关代码组织的信息。
1. 定义符号和取消符号定义的预处理指令#define 和 #undef
预处理指令都以#号开头并位于行首前面可以出现空格符。
#define DEBUG #define ISSAY
上面的语句定义了连个个预编译的符号,他的作用域是他所处整个文件,定义符号的语句必须出现在所有代码之前, 否则编译的时候会出现一个异常: 不能在文件的第一个标记之后,定义或取消定义预处理器符号 。我们也可以使用#undef来取消一个符号的定义,先来看个例子。
- #define DEBUG
- #undef DEBUG
- #define ISSAY
- using System;
- namespace JustDoIt
- {
- class Program
- {
- static void Main(string[] args)
- {
- #if DEBUG
- Console.Write("debug.");
- #endif
- #if ISSAY
- Console.Write("hello.");
- #else
- Console.Write("you can say nothing.");
- #endif
- Console.ReadLine();
- }
- }
- }
- //输出:hello
#define DEBUG #undef DEBUG #define ISSAY using System; namespace JustDoIt { class Program { static void Main(string[] args) { #if DEBUG Console.Write("debug."); #endif #if ISSAY Console.Write("hello."); #else Console.Write("you can say nothing."); #endif Console.ReadLine(); } } } //输出:hello
从上面的代码我们可以看到第一样等一了符号DEEBU,紧接着第二行取消了这个符号的定义,也就是相当于没有定义一样,所以程序运行的时候不会执行Console.Write("debug.")这个语句。第三行定义了ISSAY符号,所以程序输出了“hello”,如果我们把他注释了或者是删除了,那么程序会输出“you can say nothing“。我们可以初步看到通过定义预编译的符号,可以控制编译器选择性地编译代码。上面的代码中还有#if和#endif这样的符号,这些是条件编译指令。
2. 条件编译指令
条件编译指令有4个,除了我们从第一个示例看到的#if、#else、#endif之外,还有一个#elif。我们对这些指令应该有是曾相识的感觉,他们跟我们平时编写代码的时候试用的条件语句是一样的,条件语句是用来控制程序流的,而这些条件编译指令是用来控制编译器选择性地编译代码的。
一条#if语句可以有0条或多条#elif语句,也可以有0条或一条#else 语句,但必须包括一条#endif语句必须有,否则会出现语法错误。
3. #region和#endregion
这两个符号平时我们肯定用的很多了,就是把一些相关的代码折叠到一起,这样对我们在一个文件中编写较长的代码非常有用,我们可以把一组相关的代码用#region和#endregion组织在一起并且可以在#region后面加上说明的文字,当这组代码被折叠起来的时候,我们可以看到#region后面的说明文字。
4. #warning、#error
这两个指令对编译器自身估计比较有用,如果我们用vs写代码的话,编译项目的时候有时就会看到错误列表窗口里列出出现的错误、警告或者消息的信息。
- #define DEBUG
- using System;
- namespace JustDoIt
- {
- class Program
- {
- static void Main(string[] args)
- {
- #if DEBUG
- #warning "debug状态,js代码不会被压缩"
- #elif RELEASE
- #warning "Release状态,js代码将会被压缩"
- #else
- #error "并清楚什么状态"
- #endif
- Console.ReadLine();
- }
- }
- }
#define DEBUG using System; namespace JustDoIt { class Program { static void Main(string[] args) { #if DEBUG #warning "debug状态,js代码不会被压缩" #elif RELEASE #warning "Release状态,js代码将会被压缩" #else #error "并清楚什么状态" #endif Console.ReadLine(); } } }
以上的代码将不会通过编译,错误的信息就是”并清楚什么状态“,也就是#error后面的信息。如果把#error这行删除或者注释掉的话,那么我们在编译程序的时候可以在错误列表窗口中看到“debug状态,js代码不会被压缩”的警告信息。
5. #line ……
总结:以上的这些指令大概只有1、2、3对我们会比较有用,不过为了文章的完整我把在网上找到的其他的符号也加进来了。
然后回到这个blog的Javascript调试问题。在vs里面可以直接在代码里面使用#DEBUG符号,下面是我的截图。
我们可以看到#if (DEBUG)下面的那样是灰色的,就是如果这个时候编译代码的话,会编译#else下面的语句,因为这个时候我把生成的方式设置为了release(我们可以在项目或者是解决方案的属性里面配置项目生成的方式)。
如果我们把项目生成的方式设置为debug的话,那么执行的就是#if (DEBUG)下面的语句,这样就直接把js文件的路径赋给了控件的src属性,这样生成的html代码是一般的sript标签,不会对js文件进行压缩,这样在调试Javascript时候便可以看到格式良好的代码了。在以release方式编译代码的时候,调用了ResolveScript()方法来对这个url做了处理,生成格式换的url会直接调用js文件处理的HttpHanddle来对js代码进行压缩。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)