刘昕鑫 C# 特性详解

C# 特性详解

特性(attribute)是被指定给某一声明的一则附加的声明性信息。

在C#中,有一个小的预定义特性集合。在学习如何建立我们自己的定制特性(custom
attributes)之前,我们先来看看在我们的代码中如何使用预定义特性。


 1 using System;
2 public class AnyClass
3 {
4 [Obsolete("Don‘t use Old method, use New method", true)]
5 static void Old( ) { }
6 static void New( ) { }
7 public static void Main( )
8 {
9 Old( );
10 }
11 }

我们先来看一下上面这个例子,在这个例子中我们使用了Obsolete特性,它标记了一个不应该再被使用的程序实体。第一个参数是一个字符串,它解释了为什么该实体是过时的以及应该用什么实体来代替它。实际上,你可以在这里写任何文本。第二个参数告诉编译器应该把使用这个过时的程序实体当作一种错误。它的默认值是false,也就是说编译器对此会产生一个警告。

当我们尝试编译上面这段程序的时候,我们将会得到一个错误:   

AnyClass.Old()‘ is
obsolete: ‘Don‘t use Old method, use New method‘

开发定制特性(custom
attributes)

现在让我们来看看如何开发我们自己的特性。

   
首先我们要从System.Attribute派生出我们自己的特性类(一个从System.Attribute抽象类继承而来的类,不管是直接还是间接继承,都会成为一个特性类。特性类的声明定义了一种可以被放置在声明之上新的特性)。

1 using System; 
2 public class HelpAttribute : Attribute
3 {
4 }

  不管你是否相信,我们已经建立了一个定制特性,现在我们可以用它来装饰现有的类就好像上面我们使用Obsolete
attribute一样。

1 [Help()]
2 public class AnyClass
3 {
4 }

  注意:对一个特性类名使用Attribute后缀是一个惯例。然而,当我们把特性添加到一个程序实体,是否包括
Attribute后缀是我们的自由。编译器会首先在System.Attribute的派生类中查找被添加的特性类。如果没有找到,那么编译器会添加
Attribute后缀继续查找。

到目前为止,这个特性还没有起到什么作用。下面我们来添加些东西给它使它更有用些。


 1 using System; 
2 public class HelpAttribute : Attribute
3 {
4 public HelpAttribute(String Descrition_in)
5 {
6 this.description = Description_in;
7 }
8 protected String description;
9 public String Description
10 {
11 get
12 {
13 return this.description;
14 }
15 }
16 }
17 [Help("this is a do-nothing class")]
18 public class AnyClass
19 {
20 }

在上面的例子中,我们给HelpAttribute特性类添加了一个属性并且在后续的部分中我们会在运行时环境中查寻它。

定义或控制特性的使用

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

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

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

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

下面让我们来做一些实际的东西。我们将会在刚才的Help特性前放置AttributeUsage特性以期待在它的帮助下控制Help特性的使用。


 1 using System;
2 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
3 public class HelpAttribute : Attribute
4 {
5 public HelpAttribute(String Description_in)
6 {
7 this.description = Description_in;
8 }
9 protected String description;
10 public String Description
11 {
12 get
13 {
14 return this.description;
15 }
16 }
17 }

先让我们来看一下AttributeTargets.Class。它规定了Help特性只能被放在class的前面。这也就意味着下面的代码将会产生错误:


1 [Help("this is a do-nothing class")] 
2 public class AnyClass
3 {
4 [Help("this is a do-nothing method")] //error
5 public void AnyMethod()
6 {
7 }
8 }

编译器报告错误如下:

AnyClass.cs: Attribute ‘Help‘
is not valid on this declaration type. 
    It is valid on ‘class‘
declarations only.

我们可以使用AttributeTargets.All来允许Help特性被放置在任何程序实体前。可能的值是:

Assembly,Module,Class,Struct,Enum,Constructor,Method,Property,Field,Event,Interface,Parameter,Delegate

All = Assembly | Module | Class | Struct | Enum | Constructor | Method |
Property | Field | Event | Interface | Parameter | Delegate

ClassMembers = Class | Struct | Enum | Constructor | Method | Property |
Field | Event | Delegate | Interface

下面考虑一下AllowMultiple =
false。它规定了特性不能被重复放置多次。


1 [Help("this is a do-nothing class")]
2 [Help("it contains a do-nothing method")]
3 public class AnyClass
4 {
5 [Help("this is a do-nothing method")] //error
6 public void AnyMethod()
7 {
8 }
9 }

它产生了一个编译期错误。 
   
AnyClass.cs: Duplicate ‘Help‘ attribute

Ok,现在我们来讨论一下最后的这个属性。Inherited, 表明当特性被放置在一个基类上时,它能否被派生类所继承。


1 [Help("BaseClass")] 
2 public class Base
3 {
4 }
5 public class Derive : Base
6 {
7 }

这里会有四种可能的组合:

1 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
2 [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
3 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
4 [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]

第一种情况:

如果我们查询(Query)(稍后我们会看到如何在运行期查询一个类的特性)Derive类,我们将会发现Help特性并不存在,因为inherited属性被设置为false。

第二种情况:

和第一种情况相同,因为inherited也被设置为false。

第三种情况:

为了解释第三种和第四种情况,我们先来给派生类添加点代码:


1 [Help("BaseClass")] 
2 public class Base
3 {
4 }
5 [Help("DeriveClass")]
6 public class Derive : Base
7 {
8 }

现在我们来查询一下Help特性,我们只能得到派生类的属性,因为inherited被设置为true,但是AllowMultiple却被设置为false。因此基类的Help特性被派生类Help特性覆盖了。

第四种情况:

在这里,我们将会发现派生类既有基类的Help特性,也有自己的Help特性,因为AllowMultiple被设置为true。

定义或控制特性的使用AttributeUsage类是另外一个预定义特性类,它帮助我们控制我们自己的定制特性的使用。它描述了一个定制特性如何被使用。

属性和特性的区别可以参考一下: http://developer.51cto.com/art/200908/147097.htm

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/Foxalien/archive/2009/12/05/4946672.aspx

时间: 2024-10-20 04:33:17

刘昕鑫 C# 特性详解的相关文章

iOS开发——高级特性&Runtime运行时特性详解

Runtime运行时特性详解 本文详细整理了 Cocoa 的 Runtime 系统的知识,它使得 Objective-C 如虎添翼,具备了灵活的动态特性,使这门古老的语言焕发生机.主要内容如下: 引言 简介 与Runtime交互 Runtime术语 消息 动态方法解析 消息转发 健壮的实例变量(Non Fragile ivars) Objective-C Associated Objects Method Swizzling 总结 引言 曾经觉得Objc特别方便上手,面对着 Cocoa 中大量

Servlet 3.0 新特性详解

转自:https://www.ibm.com/developerworks/cn/java/j-lo-servlet30/ Servlet 3.0 新特性详解 张 建平2010 年 4 月 23 日发布 WeiboGoogle+用电子邮件发送本页面 6 Servlet 3.0 新特性概述 Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布.该版本在前一版本(Servlet 2.5)的基础上提供了若干新特性用于简化 Web 应用的开发和部署.其

Atitit.jdk java8的语法特性详解 attilax 总结

Atitit.jdk java8的语法特性详解 attilax 总结 1.1. 类型推断这个特别有趣的.鲜为人知的特性1 2. Lambda1 2.1. 内部迭代意味着改由Java类库来进行迭代,而不是客户代码.例如:1 2.2. Stream 流失接口 管道(pipelines)模式2 2.3. 方法引用(Method reference)2 2.4.  默认方法(Default method)2 2.5. 生成器函数(Generator function)2 2.6. 新加入的Nashorn

Android群英传笔记——第十二章:Android5.X 新特性详解,Material Design UI的新体验

Android群英传笔记--第十二章:Android5.X 新特性详解,Material Design UI的新体验 第十一章为什么不写,因为我很早之前就已经写过了,有需要的可以去看 Android高效率编码-第三方SDK详解系列(二)--Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能 这一章很多,但是很有趣,也是这书的最后一章知识点了,我现在还在考虑要不要写这个拼图和2048的案例,在此之前,我们先来玩玩Android5.X的新特性吧!

http协议及httpd特性详解

前言 随着互联网的迅猛发展和网络的普及,各类网站层出不穷,网站也成为企业宣传和实力展现的主要途径之一,说到网站就不得不说一下web服务了,现在比较流行的web服务还是当属Apache即httpd.本文将详解http协议及httpd的特性. http协议详解 http协议 http: Hyper Text Transfer Protocol 超文本传输协议 传输文本:HTML html: Hyper Text Mark Language 超文本标记语言 html文档的生成方式 静态:纯html格式

[Android 新特性] 安卓4.4新特性详解

在本月初,谷歌的5太子google  nexus5正式发布了,还给大家带来了全新的安卓android4.4的操作系统,并且官网给大家带来了新的说法,就是安卓4.4会比之前的系统更加省电,这个到底是为什么呢?网侠小编就来说说安卓4.4的为何省电的工作机制. 首先,我们要搞清楚一个问题,那就是什么是Dalvik? 在整个Android 4.4的更新特性中,最引人瞩目的应该就是虚拟机由Dalvik转成ART,也就是“中间件”的变更(Midware).先来看看什么是Dalvik. 如图,Dalvik虚拟

C#中的 特性 详解(转载)

本篇幅转载于:http://www.cnblogs.com/rohelm/archive/2012/04/19/2456088.html C#中特性详解 特性提供了功能强大的方法,用于将元数据或声明信息与代码(程序集.类型.方法.属性等)相关联.特性与程序实体关联后,即可在运行时使用"反射"的技术查询特性. 特性具有以下属性: 特性可向程序中添加元数据.元数据是有关在程序中定义的类型的信息.所有的 .NET 程序集都包含指定的一组元数据,这些元数据描述在程序集中定义的类型和类型成员.可

c#特性详解【含常用过滤器实例】

基础拾遗 基础拾遗------特性详解 基础拾遗------webservice详解 基础拾遗------redis详解 基础拾遗------反射详解 基础拾遗------委托详解 基础拾遗------接口详解 基础拾遗------泛型详解 前言 本来7月份想着是用一个月把基础拾遗写完的,结果断断续续写了4个月了,才写了这几篇,这两天又规划着多写几篇,希望能坚持吧.两天一次和同事聊天竟然好多人都不知道,他们每天却都在用. 1.特性概念 特性(Attribute)是用于在运行时传递程序中各种元素(

【转】C#各个版本中的新增特性详解

转自:http://www.cnblogs.com/knowledgesea/p/6694979.html 序言 自从2000年初期发布以来,c#编程语言不断的得到改进,使我们能够更加清晰的编写代码,也更加容易维护我们的代码,增强的功能已经从1.0搞到啦7.0甚至7.1,每一次改过都伴随着.NET Framework库的相应支持,也不断的带给我们期待与惊喜.下面我们就对c#一路走到现在,做一个回顾与学习. C#语言目标与前行 c#的设计目标是有以下几点: 旨在是一种简单,现代,通用的面向对象编程