网站首页 > 编程文章 正文
特性(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类是另外一个预定义特性类,它帮助我们控制我们自己的定制特性的使用。它描述了一个定制特性如何被使用。
猜你喜欢
- 2024-09-09 搞懂事件——C# 的event的机制深度理解
- 2024-09-09 C 容易犯错的新手问题有哪些?(c语言容易犯错误的地方)
- 2024-09-09 想要使用C#编程创建3D PDF转换器?Aspose.PDF必不可少
- 2024-09-09 .NET 大牛之路 019 | C#基础:理解装箱与拆箱
- 2024-09-09 在CSI.EXE中使用C#脚本绕过应用白名单(含缓解方案)
- 2024-09-09 在C#中向IC卡(通常指智能卡或集成电路卡)写入数据
- 2024-09-09 C#编程中如何使用线程(c# 线程编程)
- 2024-09-09 c# 串口连接xbee模块并且发送AT命令
- 2024-09-09 iOS开发生涯的初恋:详解Objective-C多项改进
- 2024-09-09 c# 串口连接xbee模块并且发送AT命令设置NI值
你 发表评论:
欢迎- 06-24一个老爸画了超级有爱的365幅画 | 父亲节献礼
- 06-24产品小白看魏则西事件——用产品思维审视百度推广
- 06-24某教程学习笔记(一):13、脚本木马原理
- 06-24十大常见web漏洞——命令执行漏洞
- 06-24初涉内网,提权那些事(内网渗透提权)
- 06-24黑客命令第16集:47种最常见的**网站方法2/2
- 06-24铭说 | 一句话木马的多种变形方式
- 06-24Java隐藏的10倍效率技巧!90%程序员不知道的魔法方法(附代码)
- 最近发表
- 标签列表
-
- spire.doc (70)
- instanceclient (62)
- solidworks (78)
- system.data.oracleclient (61)
- 按键小精灵源码提取 (66)
- pyqt5designer教程 (65)
- 联想刷bios工具 (66)
- c#源码 (64)
- graphics.h头文件 (62)
- mysqldump下载 (66)
- libmp3lame (60)
- maven3.3.9 (63)
- 二调符号库 (57)
- git.exe下载 (68)
- diskgenius_winpe (72)
- pythoncrc16 (57)
- solidworks宏文件下载 (59)
- qt帮助文档中文版 (73)
- satacontroller (66)
- hgcad (64)
- bootimg.exe (69)
- android-gif-drawable (62)
- axure9元件库免费下载 (57)
- libmysqlclient.so.18 (58)
- springbootdemo (64)
本文暂时没有评论,来添加一个吧(●'◡'●)