zoukankan      html  css  js  c++  java
  • 《C#高效编程》读书笔记04-使用Conditional特性而不是#if条件编译

    #if/#endif语句常用来基于同一份源代码生成不同的编译结果,其中最常见的就是debug版和release版。但是这在实际应用中并不是非常友好,因为它们容易被滥用,其代码也难以理解或调试。
    C#为此添加了一个Conditional特性,该特性可以标识出某种环境设置下某个方法是否应该被调用。使用这种方式来描述条件编译要比#if/#endif更加清晰。
    下面来看几个例子:

    private void CheckStateBad()
    {
        #if
        Trace.WriteLine("Entering CheckState for Person");
    
        string methodName = new StackTrace().GetFrame(1).GetMethod().Name;
    
        Debug.Assert(lastName != null, methodName, "Last Name can not be null");
        #endif
    }
    

    最终会在release版本留下一个CheckStateBad()的空方法,虽然在release版本中CheckStateBad()什么也不做,但是方法的加载、JIT编译和调用仍然有些开销。
    而使用Conditional特性即可将一些函数拆分出来,让其只有在定义了某些环境变量或者某个值之后才能编译并成为类的一部分。

    [Conditional("DEBUG")]
    private void CheckStateBad()
    {
        //code 
    }
    

    无论是否定义了DEBUG环境变量,CheckStateBad()方法都将被编译至程序集中。这种做法看起来也似乎不那么高效,但是其中占用的仅仅是一点点磁盘空间而已。如果没有被调用,CheckStateBad()并不会加载到内存中,也不会被JIT编译。
    在应用多个Conditional特性时,它们之间的组合关系将为"或"(OR)。

    [Conditional("DEBUG"), Conditional("TRACE")]
    private void CheckStateBad()
    {
        //code 
    }
    

    而若想创建一个使用"与"(AND)关系的构造,则需要自己在源代码中定义预处理符号:

    #if (VAR1 && VAR2)
    #define BOTH
    #endif
    

    然后可以按老式做法编写CheckStateBad()方法:

    private void CheckStateBad()
    {
        #if BOTH
        //code 
        #endif
    }
    

    Conditional特性只可以应用在整个方法上。另外需要注意的是,任何一个使用Conditional特性的方法都只能返回void类型。

  • 相关阅读:
    ASP.NET Web API中通过URI显示实体中的部分字段
    ASP.NET Web API中把分页信息放Header中返回给前端
    写一个针对IQueryable<T>的扩展方法支持动态排序
    Perl处理和收走子进程(退出状态码和wait)
    Perl多进程
    Perl信号处理
    大话西游之大圣娶亲中的至尊宝和紫霞仙子
    Perl List::Util模块用法详解
    Python面向对象:杂七杂八的知识点
    Python迭代和解析(5):搞懂生成器和yield机制
  • 原文地址:https://www.cnblogs.com/kw13202/p/6767297.html
Copyright © 2011-2022 走看看