• C# 预处理指令


    导读

    1、什么是预处理

    2、预处理的好处

    3、C#中的常见预处理指令

    4、总结


    什么是预处理

            在计算机科学中,预处理通常是指利用某一程序(通常是预处理器)对某一格式的源码(如.cs C#源代码)按照一些规则进行源码替换的过程。这个过程发生在词法分析阶段,得到的仍然是源码文件。对于编译而言简单来讲可分为三个阶段,词法分析、语法分析、可执行程序的生成。

    上面是我自己的理解,可能不准确。PS我曾旁听过中科大两学期的编译原理课,但都是因为某些原因工作加班等没有一学期是坚持下去完整听完的,真心惭愧 悲伤

    预处理的好处

            这个有什么好处,我暂时还没归纳出来。日后补上

    C#中的常见预处理指令

            C#中常见预处理指令可分为4类:

    1、预处理符号定义指令 #define  和 #undef

    2、条件编译指令 #if #elif #else #endif

    3、诊断指令  #error 和 #warning

    4、region 指令 #region  #endregion

    现在一一说明

    预处理定义符号

    我们可以用 #define 定义预处理符号,用 #undef 取消预处理符号的定义,虽然编译器提供了这样的机制,但我不建议将预处理符号定义写在源代码中,因为这样就缺少变通性。C#编译器提供了一个命令可以将预处理符号的定义放在命令行参数中 csc /d:SybolName ..,推荐采用编译器命令参数的形式定义预处理符号

    条件编译指令

    #if #elif #else #endif 和C#语法if-elseif else 的语义类似,这里就不多说了。它支持 && || ! 登陆逻辑组合

    我们看个例子  demo.cs

    // #define Debug_Mode1  // 定义预处理符号  Debug_Mode1
    // #undef Debug_Mode1    // 取消定义预处理符号 Debug_Mode1
    using System;
    class App
    {
        static void Main()
        {
            #if (Debug_Mode1 && !Debug_Mode2) // 只开启 Debug_Mode1       
            Debug_Mode1();
            #elif (!Debug_Mode1 && Debug_Mode2)  // 只开启 Debug_Mode2
            Debug_Mode2();
            #elif (Debug_Mode1 && Debug_Mode2)  // 同时开启 Debug_Mode1和Debug_Mode2
            Debug_Mode1();
            Debug_Mode2();
            #else
            Console.WriteLine("正常运行");
            #endif 
        }
        
        #if(Debug_Mode1)
        static void Debug_Mode1()
        {
            Console.WriteLine("开启Debug_Mode1模式");
        }
        #endif
        
        #if(Debug_Mode2)
        static void Debug_Mode2()
        {
            Console.WriteLine("开启Debug_Mode2模式");
        }
        #endif
    }

    编译命令分别为

    csc demo.cs

    csc /d:Debug_Mode1 demo.cs

    csc /d:Debug_Mode2 demo.cs

    csc /d:Debug_Mode1,Debug_Mode2 demo.cs

    运行效果分别为

    image

    image

    image

    image

     

    诊断指令

    格式
    #error message
    #waming message
    message 可以是任何格式文本,比如中文

    看代码  diaDemo.cs

    using System;
    #warning 编译代码前必须先Git代码 如已经Git过代码可无视
    class App
    {
        static void Main()
        {
            DebugInvoke();
            #if !Debug_Mode
            Console.WriteLine("正常运行");
            #endif
        }
        
        static void DebugInvoke()
        {       
    #if !Debug_Mode
    #error 这个方法只能在调试模式中使用
    #endif    
            Console.WriteLine("现在进入调试模式...");
        }
    }

    编译命令分别为

    csc diaDemo.cs

    csc /d:Debug_Mode diaDemo.cs

    效果分别为

    image

    image

     

    region 指令

    这个指令我想用过C#的都应该熟悉,略去不表

     

    总结

    1、源文件中的任何 #define 和 #undef 指令都必须出现在源文件中的一个C#标识符前面,否则将出现编译时错误

    2、不建议用#define 方式在源代码中定义预编译符号,建议采用编译器命令行参数的方式定义预编译符号

    3、预处理符号定义是在编译时指定不是运行时指定

    看一个运行时指定运行参数的例子  demo2.cs

    using System;
    
    class App
    {
        static void Main(string[] args)
        {
            foreach(string arg in args)
            {
                Console.WriteLine(arg);
            }
        }
    }

    编译命令 csc demo2.cs

    运行效果

    image

     

    本文完

  • 相关阅读:
    JAVA 编写测试类出现的问题(二)使用junit4测试的时候出现java.lang.NullPointerException
    JAVA 编写测试类出现的问题(三)java.lang.NoClassDefFoundError: org/springframework/core/annotation/MergedAnnotations
    线程当中注入Service的时候,程序一直在报NullPointerException
    微服务当中使用openfeign做远程调用的时候,丢失请求头信息
    Interceptor拦截器当中注入Service报空指针异常
    sql server 数据库可疑解决方案 L
    server sql 无法访问本地127.0.0.1报错问题 yongqi
    vue 路由切换过渡动效 滑入 滑出效果
    物联网平台ThingsKit
    不重启服务器在线扩容FCSAN存储
  • 原文地址:https://www.cnblogs.com/Aphasia/p/4355020.html
Copyright © 2020-2023  润新知