zoukankan      html  css  js  c++  java
  • .NET预处理器指令

    .NET预处理器指令

      做开发以来很少接触到这部分内容,基本上没有用到,偶尔在一些框架中和一些开源项目中会见到,常常因为只关心实现逻辑忽略了这部分的功能。现在自己有点时间了,还是希望能够完整的对这部分做个了解。

    #define和#undef

      可以使用 #define 指令或 /define 编译器选项定义符号。

      使用 #define 可以定义一个符号,并通过将该符号用作表达式传递给条件编译 (#if) 指令,使该表达式的计算结果为 true

      符号可用于指定编译的条件。可以使用 #if 或 #elif 来测试符号。还可以使用 conditional 属性执行条件编译。

      可以定义符号,但是无法对符号赋值。#define 指令必须在使用任何也不是指令的指令之前出现在文件中。

      用 #define 创建的符号的范围是在其中定义该符号的文件。

    // 定义一个符号
    #define
    DEBUG

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

    // 取消定义符号
    #undef DEBUG
     1 // preprocessor_undef.cs
     2 // compile with: /d:DEBUG
     3 #undef DEBUG
     4 using System;
     5 class MyClass 
     6 {
     7     static void Main() 
     8     {
     9 #if DEBUG
    10         Console.WriteLine("DEBUG is defined");
    11 #else
    12         Console.WriteLine("DEBUG is not defined");
    13 #endif
    14     }
    15 }

    // 输入:DEBUG is not defined

    #if、#elif、#else和#endif

      条件编译指令用来根据条件将部分代码段包括进来或排除在外。

      #if 使您可以开始条件指令,测试一个或多个符号以查看它们是否计算为 true。如果它们的计算结果确实为 true,则编译器将计算位于 #if 与最近的 #endif 指令之间的所有代码。

      可以使用运算符 ==(相等)、!=(不相等)、&&(与)及 ||(或)来计算多个符号。还可以用括号将符号和运算符分组。

      以 #if 指令开始的条件指令必须用 #endif 指令显式终止。

    // preprocessor_if.cs
    
    #define DEBUG
    #define VC_V7
    
    using System;
    
    public class MyClass 
    {
        static void Main() 
        {
    #if (DEBUG && !VC_V7)
            Console.WriteLine("DEBUG is defined");
    #elif (!DEBUG && VC_V7)
            Console.WriteLine("VC_V7 is defined");
    #elif (DEBUG && VC_V7)
            Console.WriteLine("DEBUG and VC_V7 are defined");
    #else
            Console.WriteLine("DEBUG and VC_V7 are not defined");
    #endif
        }
    }
    
    // 输出:DEBUG and VC_V7 are defined

    Conditional Attribute

      [Conditional("DEBUG")]属性作用在方法上,并指定一个预处理符号。如果预处理符号被定义了(计算结果为true),则能正常调用该方法;否则省略对该方法的调用。

    class Debug
        {
            static void Main(string[] args)
            {
    
                Print1();
                Print2();
                Print3();
    
                Console.ReadLine();
            }
    
            [Conditional("DEBUG")]
            static void Print1()
            {
                Console.WriteLine("Print1");
            }
    
            // 定义了debug或者trace后才执行
            // 或者的关系
            [Conditional("DEBUG"), Conditional("Trace")]
            static void Print2()
            {
                Console.WriteLine("Print2");
            }
    
            // 只有定义了Debug和Trace后才会执行此方法
            [Conditional("DEBUGAndTrace")]
            static void Print3()
            {
                Console.WriteLine("Print3");
             }
        }

    #warning和#error

      #warning 使您得以从代码的特定位置生成一级警告。#error 使您可以从代码中的特定位置生成错误。

      #warning 和#error 通常用在条件指令中。

     1 // preprocessor_warning.cs
     2 // CS1030 expected
     3 
     4 #define DEBUG
     5 
     6 class MainClass 
     7 {
     8     static void Main() 
     9     {
    10 #if DEBUG
    11 #warning DEBUG is defined
    12 #endif
    13     }
    14 }

    #region和#endregion

      #region 使您可以在使用 Visual Studio 代码编辑器的大纲显示功能时指定可展开或折叠的代码块。

      #region 块必须以 #endregion 指令终止。

    #region MyClass definition
    public class MyClass 
    {
        static void Main() 
        {
        }
    }
    #endregion

    #line

      #line 使您可以修改编译器的行号以及(可选)错误和警告的文件名输出。下面的示例说明如何报告与行号关联的两个警告。#line 200 指令强迫行号为 200(尽管默认值为 #7)。另一行 (#9) 作为默认 #line 指令的结果跟在通常序列后。

     1 class MainClass
     2 {
     3 
     4     static void Main() 
     5     {
     6 #line 200
     7         int i;    // CS0168 on line 200
     8 #line default
     9         char c;   // CS0168 on line 9
    10     }
    11 }

      #line hidden 指令对调试器隐藏若干连续的行,这样当开发人员在逐句通过代码时,将会跳过 #line hidden 和下一个 #line 指令(假定它不是另一个 #line hidden 指令)之间的所有行。

      #line hidden 指令不会影响错误报告中的文件名或行号。

      #line filename 指令指定您希望出现在编译器输出中的文件名。默认情况下,使用源代码文件的实际名称。文件名必须括在双引号 ("") 中。

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

    // preprocessor_linehidden.cs
    using System;
    class MainClass 
    {
        static void Main() 
        {
            Console.WriteLine("Normal line #1."); // Set break point here.
    #line hidden
            Console.WriteLine("Hidden line.");
    #line default
            Console.WriteLine("Normal line #2.");
        }
    }

    #pragma、#pragma warning和#pragma checksum

      #pragma 用于给编辑器提供特殊的指令,说明如何编译包含杂注的文件。

    #pragma pragma-name pragma-arguments
    参数:
        pragma-name:可识别杂注的名称。
        pragma-arguments:杂注特定的参数。

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

    #pragma warning disable warning-list
    #pragma warning restore warning-list
    参数:
        warning-list
        警告编号的逗号分隔列表。只输入数字,不包括前缀 "CS"。
        当没有指定警告编号时,disable 禁用所有警告,而 restore 启用所有警告。
    // pragma_warning.cs
    using System;
    
    #pragma warning disable 414, 3021
    [CLSCompliant(false)]
    public class C
    {
        int i = 1;
        static void Main()
        {
        }
    }
    #pragma warning restore 3021
    [CLSCompliant(false)]  // CS3021
    public class D
    {
        int i = 1;
        public static void F()
        {
        }
    }

      #pragma checksum 可用于生成源文件的校验和,以帮助调试 ASP.NET 页。

      Visual Studio 调试器使用校验和来确保找到的总是正确的源。编译器计算源文件的校验和,然后将输出发出到程序数据库 (PDB) 文件。最后,调试器使用 PDB 来比较它为源文件计算的校验和。

      此解决方案不适用于 ASP.NET 项目,因为算出的是生成的源文件而不是 .aspx 文件的校验和。为解决此问题,#pragma checksum 为 ASP.NET 页提供了校验和支持。

      在 Visual C# 中创建 ASP.NET 项目时,生成的源文件包含 .aspx 文件(从该文件生成源文件)的校验和。然后,编译器将此信息写入 PDB 文件。

      如果编译器在该文件中没有遇到 #pragma checksum 指令,它将计算校验和,然后将算出的值写入 PDB 文件。

    #pragma checksum "filename" "{guid}" "checksum bytes"
    参数:
        "filename"
        要求监视更改或更新的文件的名称。
        "{guid}"
        文件的全局唯一标识符 (GUID)。
        "checksum_bytes"
        十六进制数的字符串,表示校验和的字节。必须是偶数位的十六进制数。奇数位的数字会导致编译时警告,从而使指令被忽略。
  • 相关阅读:
    将博客搬至CSDN
    小啃机器学习(1)-----ID3和C4.5决策树
    然爸读书笔记(2014-12)----20个月赚130亿
    然爸读书笔记(2014-11)----小米的尖叫
    然爸读书笔记(2014-10)----Bootsrap用户手册
    然爸读书笔记(2014-9)----互联网思维到底是什么
    然爸读书笔记(2014-8)----结果第一
    论文阅读(2014-2)----The YouTube Video Recommendation System
    然爸读书笔记(2014-7)----平台战略
    扎克伯格谈Facebook创业过程
  • 原文地址:https://www.cnblogs.com/whai/p/4806621.html
Copyright © 2011-2022 走看看