Fork me on GitHub
C# 预处理器指令

C# 预处理器指令

介绍

预处理指令是由编译器解释的命令,并影响输出或生成过程中的行为. 使用术语“预处理指令”只是为了与 C 和 C++ 编程语言保持一致。在 C# 中没有单独的预处理步骤,不像C和C++中,你不可以使用这些指令创建宏。预处理指令总是占用源代码中的单独一行,并且总是以 # 字符和预处理指令名称开头。# 字符的前面以及 # 字符与指令名称之间可以出现空白符。

接下来我们看看有关以下 C# 预处理器指令的信息:

#IF

如果 C# 编译器遇到最后面跟有 #endif 指令的 #if 指令,则仅当指定的符号已定义时,它才会编译这两个指令之间的代码。
C# 中的 #if 语句是 Boolean,仅测试符号是否已定义。
运算符 &&(与)和 ||(或)可用来评估多个符号是否已定义。 还可以用括号将符号和运算符分组。
结合使用 #if 与 #else、#elif、#endif、#define 和 #undef 指令,可以根据一个或多个符号是否存在来包含或排除代码。在编译调试版本的代码或针对特定配置进行编译时,这会很有用。
以 #if 指令开始的条件指令必须用 #endif 指令显式终止。

#Else

#else 允许您创建复合条件指令,因此,如果前面的 #if 或(可选)#elif 指令中的任何表达式都不为 true,则编译器将计算 #else 与后面的 #endif 之间的所有代码。

#Elif

#elif 使您得以创建复合条件指令。如果前面的 #if 和前面的任何 #elif(可选)指令表达式的计算结果都不是 true,则将计算 #elif 表达式。如果 #elif 表达式计算为 true,编译器将计算位于 #elif 和下一个条件指令之间的所有代码。
使用 #elif 更简单,因为每个 #if 都需要一个 #endif,而 #elif 即使在没有匹配的 #endif 时也可以使用。

#Endif

#endif 指定以 #if 指令开头的条件指令的结尾

#Define

#define 可让您定义符号。 当您将符号用作传递给 #if 指令的表达式时,此表达式的计算结果为 true

注意:不能像在 C 和 C++ 中的通常做法一样,使用 #define 指令来声明常数值。最好是将 C# 中的常数定义为类或结构的静态成员。如果具有多个像这样的常数,可以考虑创建一个单独的“Constants”类来保存这些常数。

针对以上指令我们提供一段代码:

如上所示:由于DEBUG 和 MYTEST都定义了,所以,如下代码

#elif (DEBUG && MYTEST)
Console.WriteLine("DEBUG and MYTEST are defined");

高亮显示可用,其他行代码置灰。

运行结果:

#Undef
#undef 使您可以取消符号的定义,以便通过将该符号用作 #if 指令中的表达式,使表达式的计算结果为 false。

示例代码:

复制代码
#define DEBUG
#undef DEBUG
using System;
class MyClass
{
    static void Main()
    {
#if DEBUG
        Console.WriteLine("DEBUG is defined");
#else
        Console.WriteLine("DEBUG is not defined");
#endif
    }
}
复制代码

运行结果:

#Warning
#warning 使您得以从代码的特定位置生成一级警告。 例如:

复制代码
#define DEBUG
class MainClass
{
    static void Main()
    {
#if DEBUG
#warning DEBUG is defined
#endif
    }
}
复制代码

#Error 

#error使您可以从代码中的特定位置生成错误。例如:

复制代码
#define DEBUG
class MainClass
{
    static void Main()
    {
#if DEBUG
#error DEBUG is defined
#endif
    }
}
复制代码

#Region

#region 是大家最为熟悉的指令,它使您可以在使用 Visual Studio 代码编辑器的大纲显示功能时指定可展开或折叠的代码块。 在较长的代码文件中,能够折叠或隐藏一个或多个区域会十分便利,这样,您可将精力集中于当前处理的文件部分。 下面的示例演示如何定义区域:

复制代码
#region MyClass definition
public class MyClass
{
    static void Main()
    {
    }
}
#endregion
复制代码

#region 块必须以 #endregion 指令终止。
#region 块不能与 #if 块重叠。但是,可以将 #region 块嵌套在 #if 块内,或将 #if 块嵌套在 #region 块内。

#endregion

#endregion 标记 #region 块的结尾

#line
#line 使您可以修改编译器的行号以及(可选)错误和警告的文件名输出。 下面的示例说明如何报告与行号关联的两个警告。 #line 200 指令将行号强制设置为 200(尽管默认行号为 #7),在执行下一条 #line 指令之前,文件名将报告为“Special”。 #line default 指令将行号恢复为默认行号,默认行号对前一条指令重新编号的行进行计数。

输出结果:

备注
#line 指令可能由生成过程中的自动中间步骤使用。例如,如果行从原始的源代码文件中移除,但是您仍希望编译器基于文件中的原始行号生成输出,则可以移除行,然后用 #line 模拟原始行号。
#line hidden 指令对调试器隐藏若干连续的行,这样当开发人员在逐句通过代码时,将会跳过 #line hidden 和下一个 #line 指令(假定它不是另一个 #line hidden 指令)之间的所有行。此选项也可用来使 ASP.NET 能够区分用户定义的代码和计算机生成的代码。尽管 ASP.NET 是此功能的主要使用者,但很可能将有更多的源生成器使用它。
#line hidden 指令不会影响错误报告中的文件名或行号。即,如果在隐藏块中遇到错误,编译器将报告当前文件名和错误的行号。
#line filename 指令指定您希望出现在编译器输出中的文件名。默认情况下,使用源代码文件的实际名称。文件名必须用双引号 ("") 引起来且前面必须带一个行号。
源代码文件可以具有 #line 指令的任何编号。

示例 1
下面的示例说明调试器如何忽略代码中的隐藏行。运行此示例时,它将显示三行文本。但是,当设置如示例所示的断点并按 F10 键逐句通过代码时,您将看到调试器忽略了隐藏行。还请注意,即使在隐藏行上设置断点,调试器仍会忽略它。

#pragma

#pragma 为编译器提供特殊的指令,以说明如何编译包含杂注的文件。 这些指令必须是编译器支持的指令。 也就是说,不能使用 #pragma 创建自定义预处理指令。Microsoft C# 编译器支持以下两个 #pragma 指令:
#pragma warning
#pragma checksum

在日常开发的过程中我们总是会经常对代码进行编译,而在编译的过程中会出现许多信息,许多无用的警告信息总是会在编译过程中提示出来,以干扰一些主要的警告,对此也是可以通过预处理器指令来进行关闭来阻止其显示。


#pragma warning 可启用或禁用某些警告。

在创建的项目中,打开“输出”窗口(这样可以查看输出的警告编号:如(CS0414)):Debug->Windows->Output,如下图所示:

 

然后我们做个测试:

复制代码
using System;
class MainClass
{
    static void Main()
    {
        int i = 5;
        Console.ReadLine();
    }
}

public class test
{
    int i = 10;
}
复制代码

对于如上代码,经过编译后出现如下类似警告:“变量i被分配,但从来没有使用过它的值”。

如果我们不想显示这些警告,可通过:#pragma warning disable 警告编号1, 警告编号2,来消除。
如上图所示,警告编号分别为CS0219,CS0414
注意:消除的编号不带”CS”,如下代码:

复制代码
#pragma warning disable 0219,0414
using System;
class MainClass
{
    static void Main()
    {
        int i = 5;
        Console.ReadLine();
    }
}

public class test
{
    int i = 10;
}
复制代码

编译项目查看输出结果:

没有警告了。

如果我们又想显示CS0414怎么办呢?
可以使用#pragma warning restore 警告编号1
如下代码:

复制代码
#pragma warning disable 0219,0414
using System;
class MainClass
{
    static void Main()
    {
        int i = 5;
        Console.ReadLine();
    }
}
#pragma warning restore 0414
public class test
{
    int i = 10;
}
复制代码

编译项目,查看输出结果:

CS0414警告又显示出来了。

#pragma checksum

关于#pragma checksum指令我没能理解,google了一下也没找到相关示例。

这里给出MSDN链接:http://msdn.microsoft.com/zh-cn/library/vstudio/ms173226.aspx

大家可以自行参考,希望熟悉的朋友可以给出解释和示例,帮助大家。

 

 

摘要: 介绍预处理指令是由编译器解释的命令,并影响输出或生成过程中的行为. 使用术语“预处理指令”只是为了与 C 和 C++编程语言保持一致。在 C# 中没有单独的预处理步骤,不像C和C++中,你不可以使用这些指令创建宏。预处理指令总是占用源代码中的单独一行,并且总是以 #字符和预处理指令名称开头。#字符的前面以及 # 字符与指令名称之间可以出现空白符。接下来我们看看有关以下 C# 预处理器指令的信息:#IF如果 C# 编译器遇到最后面跟有 #endif 指令的 #if 指令,则仅当指定的符号已定义时,它才会编译这两个指令之间的代码。C# 中的 #if 语句是 Boolean,仅测试符号是否已定义。运阅读全文
posted @ 2013-04-03 12:12 程序员蛋子 阅读(743) | 评论 (1) 编辑
 
摘要: 在读本文前请看上文:ValueInjecter-基于公约的映射(初体验1)flat from one type to another//创建如下两个类 public class Foo { public Foo Foo1 { get; set; } public Foo Foo2 { get; set; } public string Name { get; set; } public int Age { get; set; } } public class FlatFoo { public s...阅读全文
posted @ 2013-04-02 13:39 程序员蛋子 阅读(10) | 评论 (0) 编辑
 
摘要: Unity 应用程序块(Unity)是一个轻量级、可扩展的依赖注入容器,支持构造函数、属性和方法调用注入。它为开发人员提供了如下好处:简化了对象的创建,尤其是分层的对象结构和依赖。允许开发人员在运行时或者配置中指定依赖的需求抽象,以及简化了横切关注点的管理。服务定位功能允许客户代码保存或者缓存容器。这在开发人员可以持久化容器到 ASP.NET Session 或者 Application 中的 ASP.NET Web 应用程序中特别有用。依赖注入(DI)——控制反转——IOC控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦阅读全文
posted @ 2013-04-02 01:36 程序员蛋子 阅读(16) | 评论 (0) 编辑
 
摘要: 最近下载了vs2012,可是这个主题实在不适应,能不能改为vs2010的样式呢,搜索了一下,操作如下:进入这个页面:http://visualstudiogallery.msdn.microsoft.com/366ad100-0003-4c9a-81a8-337d4e7ace05下载:vs2012颜色主题编辑器——ColorThemeEditor.vsix,关闭所有打开的项目,安装ColorThemeEditor.vsix。再打开Vs2012,如下所示:点击Blue主题即可。如果你以后还想换别的主题,选择-工具->更改颜色主题(Change Color Theme)或者定制主题(Cust阅读全文
posted @ 2013-03-30 12:54 程序员蛋子 阅读(4) | 评论 (0) 编辑
 
摘要: 原文地址:http://www.codeproject.com/Articles/281615/Simple-but-Interesting-Features-of-VS-2010本文并不是对原文逐句翻译,为了尽量通俗易懂,本人对原文有所增删,由于本人英语水平有限,若有歧义或错误请指正,O(∩_∩)O~。介绍VS 2010和C#4.0引入了许多新功能。在这篇文章中,我来展示一些简单但非常有用的功能。1、隐藏选定的部分代码很多时候,我们想要隐藏指定的一段代码而不是隐藏整个区域。这个在VS2010中很容易实现,只需选择要隐藏的代码,点击鼠标右键选择:大纲显示->隐藏选定内容。如下图:你选择的阅读全文
posted @ 2013-03-25 20:54 程序员蛋子 阅读(1804) | 评论 (5) 编辑
 
摘要: 这两天摸索了一下Windows服务调用quartz.net,在这里分享一下下,欢迎同学们给建设性的意见。还是先大概介绍下quartz.net: 你曾经需要应用执行一个任务吗?这个任务每天或每周星期二晚上11:30,或许仅仅每个月的最后一天执行。一个自动执行而无须干预的任务在执行过程中如果发生一个严重错误,应用能够知到其执行失败并尝试重新执行吗?你和你的团队是用.NET编程吗?如果这些问题中任何一个你回答是,那么你应该使用Quartz.NET调度器。 Quartz.NET允许开发人员根据时间间隔(或天)来调度作业。它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联。整合了 Qua阅读全文
posted @ 2011-08-09 16:38 程序员蛋子 阅读(2296) | 评论 (19) 编辑
 
摘要: 这两天给别的部门写个接口,用到WebService ,在这里做个小总结,本人菜鸟,说的比较浅,本着交流的目的,不到之处,希望各位同学能给出建设性的意见。Web Service的基本概念估计大家都比较的熟悉,我就不多说了。咱直接从头动手吧:1,首先创建一个Web网站,我这里取名叫WebServiceStudy, 在WebServiceStudy站点中添加新项 选择"Web 服务",我这里取名为WebServiceStudy.asmx。2,创建好web服务后,我们就可以在App_Code/WebServiceStudy.cs下开始我们要写的接口方法了。由于前两步骤比较简单,大部阅读全文
posted @ 2011-08-05 13:46 程序员蛋子 阅读(2512) | 评论 (22) 编辑
 
 
分类: .net
posted on 2013-04-03 22:19  HackerVirus  阅读(300)  评论(0编辑  收藏  举报