http://www.cnblogs.com/JiangSoney/archive/2009/08/10/1543197.html

.net框架提供了一个特性:属性(Attribute),注意:此属性非彼属性(property)(这都是翻译惹的祸)。

.net框架提供了两种类型的Attribute属性:内置属性,自定义属性。顾名思义,内置属性是框架已经为我们开发好的在语言中置入的属性,自定义属性是用户自行定义、创建的属性。其中条件属性(Conditional Attribute)就是属于内置属性。.net框架提供了数百个预先定义好的内置属性,这就不多说了。下面简单的说一下怎么创建用户自定义属性,从而帮助我们理解什么是Attribute属性。

首先要搞清楚:设计实现自定义属性本质就是设计实现一个自定义的类,这个类除了要满足一般类的要求外还要满足以下几个条件:

1、继承System.Attribute;

2、给该类添加AttributeUsageAttribute属性,限制属性类的用法,通过AttributeUsageAttribute类的AttributeTargets参数来指定属性类可以用于何处。如将属性类用于类、结构或者方法等等。

举例说明:

创建一个新的属性ClassInfo,记录类的创建时间。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
public class ClassInfoAttribute : Attribute
{private string _createDate;public ClassInfoAttribute(string createDate){_createDate = createDate;}public string createDate{get{return _createDate;}}
}

测试类:

[ClassInfo("2009-08-10")]
public class TClass
{public string GetAttribute(){MemberInfo memInfo = typeof(TClass);Object[] attributes = memInfo.GetCustomAttributes(typeof(ClassInfoAttribute), false);if (0 != attributes.GetLength(0)){ClassInfoAttribute item = attributes[0] as ClassInfoAttribute;if (null != item){return item.createDate;}}return string.Empty;}[Conditional("DEBUG")]public virtual void TestAtDebug(){Console.WriteLine("Test at debuging condition.");}public void Test(){Console.WriteLine("Test at normal condition.");}
}

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

[Conditional("DEBUG")]
public virtual void TestAtDebug()
{Console.WriteLine("Test at debuging condition.");
}public void Test()
{Console.WriteLine("Test at normal condition.");
}

在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快修饰,即使这样你也应该将该段代码封装到一个方法中。
再来看个例子:

public class Name
{private string _firstName;public string FirstName{set{CheckName2(value);_firstName = value;}}private void CheckName1(string item){
#if DEBUGDebug.Assert(!string.IsNullOrEmpty(item), "Name cannot be empty!");
#endif}[Conditional("DEBUG")]private void CheckName2(string item){if (string.IsNullOrEmpty(item))Console.WriteLine("Name cannot be empty!");}}

虽然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、能更好的区分条件代码和普通代码。

转载于:https://www.cnblogs.com/gsk99/p/4939401.html

尽量使用条件属性(Conditional Attribute)而不是#if/#endif预处理相关推荐

  1. [转]Effective C#原则4:用条件属性而不是#if

    使用#if/#endif 块可以在同样源码上生成不同的编译(结果),大多数debug和release两个版本.但它们决不是我们喜欢用的工具.由于#if/#endif很容易被滥用,使得编写的代码难于理解 ...

  2. 编写windows 控件需要注意的几个标签属性(Attribute)

    我们在编程控件(Control)或者是组件(Component)的时候总是要暴露一些属性(Property,不同于Attribute)给用户进行配置,以得到可以变化的功能. mapserver .NE ...

  3. attribute java c_属性别名(Attribute Aliasing)

    属性别名(Attribute Aliasing) 属性别名用于将成员变量序列化为XML属性. 让我们再次修改我们的示例并将以下代码添加到其中.xstream.useAttributeFor(Stude ...

  4. [react] 为什么属性使用className而不是class呢?

    [react] 为什么属性使用className而不是class呢? class是关键字 js会使用dom.className获取样式名,跟js保持一致 个人简介 我是歌谣,欢迎和大家一起交流前后端知 ...

  5. [html] HTML全局属性(global attribute)有哪些(包含H5)?

    [html] HTML全局属性(global attribute)有哪些(包含H5)? classiddatatypehrefstylewidthheighttargecheckeddisabledr ...

  6. C# 使用Conditional特性而不是#if条件编译

    概述 #if/#endif 语句常用来基于同一份源码生成不同的编译结果,其中最常见的就是debug版和release版.但是这些工具在实际应用中并不是非常友好,因为它们容易被滥用,其代码页进而难以理解 ...

  7. CSharpGL(30)用条件渲染(Conditional Rendering)来提升OpenGL的渲染效率

    CSharpGL(30)用条件渲染(Conditional Rendering)来提升OpenGL的渲染效率 当场景中有比较复杂的模型时,条件渲染能够加速对复杂模型的渲染. 条件渲染(Conditio ...

  8. 重构条件-Decompose Conditional分解条件式一

    重构条件-Decompose Conditional分解条件式一 1.分解条件式 1.1.使用场景 你有一个复杂的条件(if-then-else)语句.从if.then.else三个段落中分别提炼出独 ...

  9. C#特性(属性)Attribute

    先明确一个概念: 元数据..NET中元数据是指程序集中的命名空间.类.方法.属性等信息.这些信息是可以通过Reflection读取出来的. 再来看个例子: #define BUG //#define ...

  10. Spring Boot 条件注解@Conditional介绍

    一.概述 Spring Boot 是自以为是的,当 Spring Boot 在classpath中找到相关依赖项时,它会为模块提供默认(自动)配置. 举例,Spring Boot 提供了: 如 cla ...

最新文章

  1. YOLOv5导出jit,onnx,engine
  2. logback 的拆分 Appender
  3. GitLab初次安装后,登录GitLab网页的管理员账号和密码各是什么?
  4. java获取实体类的属性和值
  5. 道德经和译文_老子《道德经》第九章原文、注释、译文、导读及解析(收藏版)...
  6. sql java 创建数据库_java动态创建数据库(sql server)
  7. 学习opencv 英文版_B站上适合程序员的学习资源【赶紧收藏!】
  8. Java使用iText生成word文件的完美解决方案(亲测可行)
  9. 关于域名注册、投资问题的相关解释
  10. JavaWeb项目架构之Kafka分布式日志队列
  11. unity3d 双人巡逻兵网络游戏
  12. ajax请求数据 ztree_ztree通过ajax获取json并勾选checkbook
  13. 新连接、新生意、新生态,专访快手商业生态开放平台
  14. 基于单片机的电子时钟设计(keil+protues仿真,含代码及原理图)
  15. mysql connector详解_MySQL Connector 编程
  16. python pip什么意思_python中的pip是什么意思
  17. BI Publisher 模板开发语法大全
  18. Surface pro 4 使用心得
  19. 浅谈跨站请求伪造(CSRF)
  20. c语言qq密码程序设计,【转】C语言实现QQ密码大盗

热门文章

  1. paip.输入法编程----一级汉字1000个
  2. paip.svn不能提交CLEARUP不起作用解决方法
  3. paip.SOCKET抓包工具总结V2012.9.17
  4. 讲真,灾备的内涵其实很丰富
  5. 阿里彭蕾:CEO如何对抗孤独感?
  6. 樱桃OTC前工程师感恩自白
  7. 天津市计算机网络应用大赛,2017年天津市中等职业学校“圣纳·新道杯”技能大赛计算机应用技术技能比赛在我校开赛...
  8. NLP对放射科医生的评价
  9. pg数据库生成随机时间_postgreSQL自动生成随机数值的实例
  10. 服务器指令学习记录-----ska暑期训练