zoukankan      html  css  js  c++  java
  • c#尽量使用条件属性(Conditional Attribute)

    至此我们应该对Attribute属性大体了解了。下面来看看条件属性(Conditional Attribute)到底是怎么回事。

    1 [Conditional("DEBUG")]
     2         public virtual void TestAtDebug()
     3         {
     4             Console.WriteLine("Test at debuging condition.");
     5         }
     6 
     7         public void Test()
     8         {
     9             Console.WriteLine("Test at normal condition.");
    10         }

       在debug环境下执行的结果是:

    Test at debuging condition.
          Test at normal condition.

        在release环境下执行的结果是:

    Test at normal condition.

    条件属性是定义方法的运行环境的。条件属性只能在方法上使用。使用条件属性的方法必须符合以下规则:

    1、   该方法必须是某个类中的方法;

    2、   该方法不能是override方法,但可以是virtual方法。注意:当该方法是virtual方法时,则在派生类中对应的override方法也具有这个属性;

    3、   该方法返回的类型必须是void类型;

    4、   该方法不能是接口的实现。

    上面讲到条件属性只能在方法上使用,所以你应该用条件属性来修饰在不同条件下使用的方法,只有当你要在不同条件下使用一块代码时才用#if/#endif快修饰,即使这样你也应该将该段代码封装到一个方法中。
        再来看个例子: 

     

    1 public class Name
     2     {
     3         private string _firstName;
     4         public string FirstName
     5         {
     6             set
     7             {
     8                 CheckName2(value);
     9                 _firstName = value;
    10             }
    11         }
    12 
    13         private void CheckName1(string item)
    14         {
    15             #if DEBUG
    16             Debug.Assert(!string.IsNullOrEmpty(item), "Name cannot be empty!");
    17             #endif
    18         }
    19 
    20         [Conditional("DEBUG")]
    21         private void CheckName2(string item)
    22         {
    23             if(string.IsNullOrEmpty(item))
    24             Console.WriteLine("Name cannot be empty!");
    25         }
    26 
    27     }


        虽然CheckName1和CheckName2的功能一样,但是你肯定会更愿意选择CheckName2方法。

    下面是Release编译的程序集被反编译后的结果:

      #if DEBUG/#endif

     


         
         [Conditional("DEBUG")]


          #if DEBUG/#endif只有在debug环境下才会被编译、执行。当编译器遇到#if语句后,编译器会检查与编译环境相关的符号是否存在,如果存在,就编译#if块中的代码,如果不存在,编译器会忽略之后的代码直到#endif。当采用Conditional属性时,不管DEBUG环境变量是否被定义,Conditional属性修饰的方法总会被编译到程序集中。这或许看上去是低效的,但这只是占用一点硬盘空间,且该方法不会被载入到内存,更不会被编译成机器代码,除非它被调用。这样做的好处是生成更高效的IL(中间语言Intermediate Language)代码,从而增强程序的可伸缩性,唯一不足的是带来了一点微不足道的硬盘空间开销。

    另外,如果过多的在程序块中添加#if/#endif块,使#if/#endif块与普通代码混在一起,容易造成程序结构的混乱,晦涩难懂。并且在调试完之后,为了使用户不会被这些调试信息弄糊涂,还需要把这些#if/#endif一个一个的去掉,这样不仅不方便而且容易引发错误。#if/#endif的这些缺点正好是Conditional属性的优点。至于Conditional属性限制方法的返回类型只能是void类型,不适应返回非void类型的方法,如果你一定要这样做,别忘了可以给方法传递out类型的参数。

    总之:Conditional属性跟#if/#endif预处理比起来,具有以下几点优势:

    1、  可以由定义标记来灵活的控制;

    2、 可以生成更高效的IL代码;

    3、 帮助你强制在条件代码上使用更好的结构;

    4、可以避免因使用#if/#endif而产生的常见的错误;

         5、能更好的区分条件代码和普通代码。

  • 相关阅读:
    每天1题算法题(4)-合并二叉树 (√)
    每天1题算法题(3)-二叉树的最大深度 (√)
    每天1题算法题(2)-二叉树的层序遍历
    每天1题算法题(1)-二叉树的中序遍历
    uni-app登录页白屏
    uni-app真机运行顶部导航栏右边按钮显示不全的问题处理
    uni-app强制横屏设置
    uni-app离线打包步骤
    银行数据仓库体系实践(18)--数据应用之信用风险建模
    银行数据仓库体系实践(17)--数据应用之营销分析
  • 原文地址:https://www.cnblogs.com/xiaohua19920/p/9604090.html
Copyright © 2011-2022 走看看