博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 特性详解
阅读量:5834 次
发布时间:2019-06-18

本文共 4954 字,大约阅读时间需要 16 分钟。

特性(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

 

你可能感兴趣的文章
Facebook Messenger测试一项基于话题展开的群聊功能
查看>>
拍照应用Snow被吐槽抄袭Snapchat,对比下就知道了
查看>>
虚拟运营商10月或大面积放号 哭穷背后仍有赢家
查看>>
Server2016开发环境配置
查看>>
让人烦躁的“机房空调噪音”该怎么解决?
查看>>
分布式光伏发电建设中的逆变器及其选型
查看>>
发展物联网 构建智能连接
查看>>
增强网络安全防御 推动物联网走向应用
查看>>
UML中关联,组合与聚合等关系的辨析
查看>>
如何应对没有需求的测试
查看>>
大数据时代,如何成为数据科学人才?
查看>>
网络战役刚打响 下波“勒索”更难防
查看>>
《Linux设备驱动开发详解 A》导读
查看>>
联想 CTO:我们为什么要预装 Superfish
查看>>
报告称 MAC 恶意软件火箭式猛增
查看>>
开源中国 8 周年,国内四大社区齐聚华为
查看>>
一文看懂小程序以及它即将对行业带来的影响
查看>>
《电路分析导论(原书第12版)》一词汇表
查看>>
Tor 社会契约
查看>>
统治世界的十大算法
查看>>