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 ( != attributes.GetLength())
{
ClassInfoAttribute item = attributes[] 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 DEBUG
Debug.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、能更好的区分条件代码和普通代码。

尽量使用条件属性(Conditional Attribute)而不是#if/#endif预处理的更多相关文章

  1. c#尽量使用条件属性(Conditional Attribute)

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

  2. 用条件属性而不是#if

    使用#if   #endif可以在同样源码上生成不同的编辑(结果),通常是调式(debug)和发布(release)版本. 但是#if/#endif很容易被滥用,使得编写的代码难以理解和调式,所以C# ...

  3. [读书笔记] 二、条件注解@Conditional,组合注解,元注解

    一.条件注解@Conditional,组合注解,元注解 1. @Conditional:满足特定条件创建一个Bean,SpringBoot就是利用这个特性进行自动配置的. 例子: 首先,两个Condi ...

  4. 反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性、字段),而不去使用Invoke方法)

    反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性.字段),而不去使用Invoke方法)   创建Delegate (1).Delegate.CreateDelegate(Type, ...

  5. 18.AutoMapper 之条件映射(Conditional Mapping)

    https://www.jianshu.com/p/8ed758ed3c63 条件映射(Conditional Mapping) AutoMapper 允许你给属性添加条件,只有在条件成立的情况下该成 ...

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

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

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

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

  8. 参数(parameter)和属性(Attribute)的区别

    参数(parameter)和属性(Attribute)的区别 区别: 来源不同: 参数(parameter)是从客户端(浏览器)中由用户提供的,若是GET方法是从URL中 提供的,若是POST方法是从 ...

  9. Effective C# 学习笔记(原则一:始终能的使用属性(property),而不是可直接访问的Data Member)

    原则一:始终能的使用属性(property),而不是可直接访问的Data Member    Always use properties instead of accessible data memb ...

随机推荐

  1. ZOJ 1024 Calendar Game

    原题链接 题目大意:2001年11月4日是一个黄道吉日,有两个人做游戏,看谁先数到这个日子.可以往后数一天,比如2号到3号,30号到31号,也可以往后数一个月.给出一个起始的日子,求能否保证先开始游戏 ...

  2. leetcode 126. Word Ladder II ----- java

    Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...

  3. 黑马程序员——JAVA基础之JDK1.5新特性高级for循环和可变参数

    ------- android培训.java培训.期待与您交流! ---------- 高级for循环   格式: for(数据类型 变量名 : 被遍历的集合(Collection)或者数组) {   ...

  4. caffe: test code Check failed: K_ == new_K (768 vs. 1024) Input size incompatible with inner product parameters.

    I0327 20:24:22.966171 20521 net.cpp:849] Copying source layer drop7I0327 20:24:22.966179 20521 net.c ...

  5. java多线程机制

    多线程使用场景 1.同时需要做两件以上事情时需要开多个线程(例如:上传功能附带进度条显示,一边做上传,一边更新进度条状态.) 2.大量同类型数据需要进行处理(导入导出大量数据) 3.office文档转 ...

  6. 使用支持向量机训练mnist数据

    # encoding: utf-8 import numpy as np import matplotlib.pyplot as plt import cPickle import gzip clas ...

  7. oracle sqlplus及常用sql语句

    常用sql语句 有需求才有动力 http://blog.csdn.net/yitian20000/article/details/6256716 常用sql语句 创建表空间:create tables ...

  8. 关于malloc申请的动态内存的问题

    http://bbs.bccn.net/thread-331344-1-1.html #include<stdio.h>#include<stdlib.h>int main(v ...

  9. 认识js函数对象(Function Object)

    认识函数对象(Function Object) 可以用function关键字定义一个函数,对于每个函数可以为其指定一个函数名,通过函 数名来进行调用.这些都是代码给用户的印象,而在JavaScript ...

  10. 如何将XSD文件以及引入import的文件生成相应的C#类。

    下将微软的 Sample Code Generator 1.4.2.1 如果链接不可以用,请到google上搜索,并安装. 拷贝要生成的XSD相关文件到安装目录,MS-DOS下进入安装目录. 执行命令 ...