• 《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类型。

  • 相关阅读:
    Android游戏开发实践(1)之NDK与JNI开发02
    SDK接入(1)之Android Facebook SDK接入
    Markdown学习
    SDK接入(3)之iOS内支付(InApp Purchase)接入
    将列【1,2,3】转换为【类别1,类别2,类别3】
    SQL Server 获取日期
    SQL Server 2000 Split方法
    java连接SqlServer2012
    前辈的js学习方法
    js学习笔记
  • 原文地址:https://www.cnblogs.com/kw13202/p/6767297.html
Copyright © 2020-2023  润新知