特性的定义:公共语言运行时允许添加类似关键字的描述声明,叫做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. 一次处理ORA-07445的历险记(转)

    ORA-07445通常是Oracle调用操作系统的资源出错时出现的[@more@] 事前没有任何征兆,下午5点左右某个关键应用的17台oracle数据库上的数据库实例陆续宕机,赶紧查看alert_lo ...

  2. 【转】Linux中history历史命令使用方法详解

    原文网址:http://os.51cto.com/art/201205/335040.htm 当你在玩Linux的时候,如果你经常使用命令行来控制你的Linux系统,那么有效地使用命令历史机制将会使效 ...

  3. bzoj1655 [Usaco2006 Jan] Dollar Dayz 奶牛商店

    Description Farmer John goes to Dollar Days at The Cow Store and discovers an unlimited number of to ...

  4. 【转】多文件目录下makefile文件递归执行编译所有c文件

    首先说说本次嵌套执行makefile文件的目的:只需make根目录下的makefile文件,即可编译所有c文件,包括子目录下的. 意义:自动化编译行为,以后编译自己的c文件时可把这些makefile文 ...

  5. DirectX 开发环境配置

      想使用DirectX开发游戏,前提是要搭建DirectX的开发环境啦. 下面我们就一起学习下DirectX开发环境搭建 1. 首先是DirectX SDK安装, 下载地址是: http://www ...

  6. java与.net比较学习系列(7) 属性

    文章摘自:http://www.cnblogs.com/mcgrady/p/3411405.html 说起属性,实际上java中没有属性这个概念,只有字段和方法,但是可以通过私有字段和声明get,se ...

  7. hdu 4923 Room and Moor (单调栈+思维)

    题意: 给一个0和1组成的序列a,要构造一个相同长度的序列b.b要满足非严格单调,且 值为0到1的实数.最后使得  sum((ai-bi)^2)最小. 算法: 首先a序列開始的连续0和末尾的连续1是能 ...

  8. XCode Could not launch &quot;&quot; failed to get the task for process

    在Xcode下编译project正常,在模拟器下执行正常,最后在真机上执行的时候出现了例如以下错误: Could not launch "FeedMeWorms" failed t ...

  9. 【Android】实现动态显示隐藏密码输入框的内容

    在设置输入密码框时,有些时候需要按钮控制输入的是“明文”或者“暗文”. 这里提供一种Android实现动态显示隐藏密码输入框的内容的方法: 主要是通过设置EditText的setTransformat ...

  10. 20. Screen

    一. Screen 1.什么是Screen     Screen 是在多个进程间多路复用一个物理终端的全屏窗口管理器,Screen 也叫会话,一个Screen 会话中可以有多个 Screen 窗口, ...