特性的定义:公共语言运行时允许添加类似关键字的描述声明,叫做attribute,它对程序中的元素进行标注,如类型、字段、方法、和属性等。attribute和.NetFramework文件的元数据保存在一起,可以用来在运行时描述你的代码,或者在程序运行的时候影响应用程序的行为。

  定制特性attribute,本质上是一个雷,其为目标元素提供关联附加信息,并在运行期以反射的方式来获取附加信息。

一、特性的通用规则。

  1、定制特性可以应用的目标元素包括:程序集(assembly)、模块(module)、类型(type)、属性(proprety)、事件(event)、字段(field)、方法(method)、参数(param)、返回值(return),不外乎这些。

  2、定制特性以[,]的形式展现,放在紧挨的元素上,多个特性可以应用于同一元素,特性间以逗号隔开,以下表达规则都是有效的:

[AttributeUsage][Flags]、[AttributeUsage,Flags]、[Flags,AttributeUsageAttribute]、[AttributeUsage(),FlagesAttribute()]

  3、attribute示例,是在编译期进行初始化,而不是运行期。

  4、C#允许以指定的前缀来表示特性所应用的目标元素,建议这样来处理,因为显示处理可以消除可能带来的二义性。如:

    [assembly:MySelfAttribute()]
[module:MySelfAttribute("小王",27)]
public class AttributeArea
{ }

  5、定制特性类型,必须直接或者间接继承自System.Attribute类,而且该类型必须有共有构造函数来创建其实例。

  6、所有自定义的特性名称都应该有个Attribute后缀,这是习惯性约定。

  7、定义特性也可以应用在其他定制特性上,因为定制特性本身也是一个类,遵守类的公有规则。例如很多时候我们的自定义定制特性会应用AttributeUsageAttribute特性,来控制如何应用新定义的特性。如:

    [AttributeUsageAttribute(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
class MyNewAttribute : System.Attribute
{ }

  8、定制特性不会影响应用元素的任何功能,只是约定了该元素具有的特质。

  9、所有非抽象特性必须具有public访问限制。

  10、特性常用语编译器指令,突破#define,#undefine,#if,#endif的限制,而且更加灵活。

  11、定制特性常用于在运行期获的代码注释信息,以附加信息来优化调试。

  12、定制特性可以应用在某些设计模式中,如工厂模式,根据附加信息来决定执行的逻辑分支,降低了系统代码的耦合度。

  13、定制特性还常用于位标记,非托管函数标记、方法废弃标记等其他方面。

二、特性的应用

  常用特性,也就是.Net已经提供的固有特性,事实上.Net框架中已经提供了丰富的固有特性由我们选用,下面选出一些常用和经典的做简单讨论。

  1、AttributeUsage

  AttributeUsage特性用于控制如何应用自定义特性到目标元素。其中属性有AttributeTargets枚举,AllowMultiple、Inherited、ValidOn等。

AttributeUsage类是另外一个预定义特性类,它帮助我们控制我们自己的定制特性的使用。它描述了一个定制特性如和被使用。 
    AttributeUsage有三个属性,我们可以把它放置在定制属性前面。第一个属性是:

ValidOn 
    通过这个属性,我们能够定义定制特性应该在何种程序实体前放置。一个属性可以被放置的所有程序实体在AttributeTargets enumerator中列出。通过OR操作我们可以把若干个AttributeTargets值组合起来。

AllowMultiple 
    这个属性标记了我们的定制特性能否被重复放置在同一个程序实体前多次。

Inherited 
    我们可以使用这个属性来控制定制特性的继承规则。它标记了我们的特性能否被继承。

  2、Flags

  Flags特性用来将枚举数值看作位标记,而非单独的数值。

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Animal animals = Animal.Dog | Animal.Cat;
Console.WriteLine(animals.ToString()); //输出 Dog,Cat 如果没有Flags特性,这里的结果将是"3" Console.ReadKey();
}
} [Flags]
enum Animal
{
Dog = 0x0001,
Cat = 0x0002,
Duck = 0x0004,
Chicken = 0x0008
}
}

  3、DllImport

  DllImport特性,可以让我们调用非托管代码,所以我们可以使用DllImport特性引入对Win32 API函数的调用。

  4、Serializable

  Serializable特性表名了应用的元素可以被序列化。

  5、Conditional

  Conditional特性,用于条件编译,在调试时使用。

三、自定义特性

  既然attribute本质上就是一个类,那么我们就可以自定义更特定的attribute来满足个性化需求,只要遵守上述的多条规则,实现一个自定义特性其实是很容易的。

    [Test("标记参数")]
public static void CannotRun()
{ } [AttributeUsage(AttributeTargets.All, Inherited = true)]
public class TestAttribute : System.Attribute
{
public TestAttribute(string message)
{
throw new Exception();
Console.WriteLine(message);
} public void RunTest()
{
Console.WriteLine("这里是自定义特性的代码!");
}
}

C# attribute_特性的更多相关文章

  1. Fis3的前端工程化之路[三大特性篇之声明依赖]

    Fis3版本:v3.4.22 Fis3的三大特性 资源定位:获取任何开发中所使用资源的线上路径 内容嵌入:把一个文件的内容(文本)或者base64编码(图片)嵌入到另一个文件中 依赖声明:在一个文本文 ...

  2. Fis3的前端工程化之路[三大特性篇之资源定位]

    Fis3版本:v3.4.22 Fis3的三大特性 资源定位:获取任何开发中所使用资源的线上路径 内容嵌入:把一个文件的内容(文本)或者base64编码(图片)嵌入到另一个文件中 依赖声明:在一个文本文 ...

  3. Fis3的前端工程化之路[三大特性篇之内容嵌入]

    Fis3版本:v3.4.22 Fis3的三大特性 资源定位:获取任何开发中所使用资源的线上路径 内容嵌入:把一个文件的内容(文本)或者base64编码(图片)嵌入到另一个文件中 依赖声明:在一个文本文 ...

  4. .NET 4.6.2正式发布带来众多特性

    虽然大多数人的注意力都集中在.NET Core上,但与原来的.NET Framework相关的工作还在继续..NET Framework 4.6.2正式版已于近日发布,其重点是安全和WinForms/ ...

  5. SQL Server 2014 新特性——内存数据库

    SQL Server 2014 新特性——内存数据库 目录 SQL Server 2014 新特性——内存数据库 简介: 设计目的和原因: 专业名词 In-Memory OLTP不同之处 内存优化表 ...

  6. 探索ASP.NET MVC5系列之~~~4.模型篇---包含模型常用特性和过度提交防御

    其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...

  7. InnoDB关键特性学习笔记

    插入缓存 Insert Buffer Insert Buffer是InnoDB存储引擎关键特性中最令人激动与兴奋的一个功能.不过这个名字可能会让人认为插入缓冲是缓冲池中的一个组成部分.其实不然,Inn ...

  8. ElasticSearch 5学习(10)——结构化查询(包括新特性)

    之前我们所有的查询都属于命令行查询,但是不利于复杂的查询,而且一般在项目开发中不使用命令行查询方式,只有在调试测试时使用简单命令行查询,但是,如果想要善用搜索,我们必须使用请求体查询(request ...

  9. HTML5新特性有哪些,你都知道吗

    一.画布(Canvas) 画布是网页中的一块区域,可所以用JavaScript在上面绘图.下面我们来创建一个画布并在上面绘制一个坦克(后面将用HTML5做一个坦克大战游戏),代码如下: <!DO ...

随机推荐

  1. LeetCode_Sum Root to Leaf Numbers

    Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number ...

  2. 深入浅出Node.js (4) - 异步编程

    4.1 函数式编程 4.1.1 高阶函数 4.1.2 偏函数用法 4.2 异步编程的优势与难点 4.2.1 优势 4.2.2 难点 4.3 异步编程解决方案 4.3.1 事件发布/订阅模式 4.3.2 ...

  3. c++ 04

    一.this指针 1. 2.应用场景 1) 2)将this指针作为函数的参数.一个对象可以通知另一个对象有关自身的地址.    教师 提问|^     V|答案    学生 交叉类问题: class ...

  4. SNMP配置和常用命令OID(转)

    博文转至:http://blog.csdn.net/susu09new/article/details/12835191 OID值表示的意义(中文) .1.3.6.1.2.1.1操作系统相关的信息,其 ...

  5. Python Open Flash Chart (pyOFC2) — Home

    Python Open Flash Chart (pyOFC2) - Home pyOFC2 Python Open Flash Chart 2

  6. 文件读写IO

    摘要:本文主要总结了以下有关文件读写的IO,系统调用与库函数. 1.初级IO函数:close,creat,lseek,open,write 文件描述符是一个整型数 1.1close 1.2int cr ...

  7. 学习Android之SharedPreferences使用

    效果图例如以下: 当我们想让自己的属性设置保存下来,这时就须要SharedPreferences. 上面这个小程序,音乐状态是保存下来的.使用的上一次退出的状态. 进入DDMS,data文件下的dat ...

  8. Android应用程序资源的编译和打包过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8744683 我们知道,在一个APK文件中,除了 ...

  9. [跟我学spring学习笔记][DI循环依赖]

    循环依赖 什么是循环依赖? 循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方. Spring容器循环依赖包括构造器循环依赖和setter循环依赖,那Spring容器如何解决循环依赖呢? ...

  10. 带CheckBox的TreeView网上出错问题解决办法

    问题描述:TreeView上传到服务器,预览效果发现节点图片不显示.展开合并功能缺失.解决办法: 以下是我个人的解决办法,最终的效果实现了,但是还有一点点小遗憾,就是页面上有基于微软的调用js的报错信 ...