本文导读
1、概念
2、自定义一个 Attribute
概念
Attribute是一个特殊的类,我们知道 .NET 程序集 具有自描述的特性(由于元数据),Attribute和.NET的元数据一起,可用来向描述你的代码,或者在程序运行的时候影响应用程序的行为。
和Attribute 密切相关的技术是反射
在.NET 框架中有许多内置的 Attribute,如序列化、安全性、DllImport等
看一个内置Attribute 的代码
using System; static class App { static void Main() { Lib l = new Lib(); l.Fct(); } } class Lib { [Obsolete] public void Fct(){} }
结果
自定义一个 Attribute
系统的Attribute我们不能修改,我们能做的是自定义Attribute。步骤如下:
1、写一个继承 System.Attribute 的类,类名是以 Attribute 结尾
2、用系统自带的AttributeUsage 设置 Attribute
AttributeUsage 中有三个成员我们需要关注 AttributeTargets、AllowMultiple 、Inherited 分别的表示 Attribute 的作用范围、是否允许多个 Attribute实例(Attribute是类,反射时创建实例)、是否允许继承
我们看例子
Inherited 的例子
目录结构
是否允许继承文件夹中有4个文件分别是 Attr.cs(自定义Attribute)、TestLib.cs(Attribute修饰的测试类)、App.cs(第三方验证程序,比如框架)、build.bat 编译命令
看代码
//Attr.cs using System; namespace XXX.Common.Attr { // 不允许属性继承 [AttributeUsage(AttributeTargets.Class,Inherited = false)] public class AAttribute : Attribute {} // 允许属性继承 [AttributeUsage(AttributeTargets.Class,Inherited = true)] public class BAttribute : Attribute {} } //--------------------------------------------------------- // TestLib.cs using System; using XXX.Common.Attr; namespace XXX.Common.Lib { [A] [B] public class BaseLib {} public class ExtendLib : BaseLib {} } //--------------------------------------------------------- // App.cs using System; using XXX.Common.Attr; using XXX.Common.Lib; using System.Reflection; namespace XXX.Common.App { static class App { static void Main() { ShowBase(); Console.WriteLine("-----------------"); ShowExtend(); } static void ShowBase() { ShowHelper(typeof(BaseLib)); } static void ShowExtend() { ShowHelper(typeof(ExtendLib)); } static void ShowHelper(MemberInfo mi) { AAttribute a = Attribute.GetCustomAttribute(mi,typeof(AAttribute)) as AAttribute; BAttribute b = Attribute.GetCustomAttribute(mi,typeof(BAttribute)) as BAttribute; Console.WriteLine(a==null ? "没有AAttribute信息" : "有AAttribute信息"); Console.WriteLine(b==null ? "没有BAttribute信息" : "有BAttribute信息"); } } }
build.bat 内容
csc /t:library Attr.cs csc /t:library /r:Attr.dll TestLib.cs csc /r:Attr.dll,TestLib.dll App.cs
运行结果:
AllowMultiple 允许重复 Attribute
看代码
// Attr.cs using System; namespace XXX.Common.Attr { // 默认AllowMultiple 为false [AttributeUsage(AttributeTargets.Class)] public class AAttribute : Attribute {} [AttributeUsage(AttributeTargets.Class,AllowMultiple=true)] public class BAttribute : Attribute {} } //----------------------------------- // TestLib.cs using System; using XXX.Common.Attr; namespace XXX.Common.Lib { [A] [A] public class Lib1{} [B] [B] public class Lib2{} }
综合例子
//Attr.cs using System; namespace XXX.Common.Attr { [AttributeUsage(AttributeTargets.All)] public class HelperAttribute : Attribute { private string _url; private string _topic; public HelperAttribute(string url) { this._url = url; } public string Url { get {return this._url;} } public string Topic { get {return this._topic;} set {this._topic = value;} } } } //--------------------------------------- // TestLib.cs using System; using XXX.Common.Attr; namespace XXX.Common.Lib { [Helper("http://cnblogs.com/Aphasia")] public class TestLib { [Helper("http://cnblogs.com/Aphasia",Topic="阿飞的博客")] public void ShowBlog(){} } } //----------------------------------------- // App.cs using System; using System.Reflection; using XXX.Common.Lib; using XXX.Common.Attr; namespace XXX.Common.Application { static class App { static void Main() { ShowHelp(typeof(TestLib)); ShowHelp(typeof(TestLib).GetMethod("ShowBlog")); } static void ShowHelp(MemberInfo mi) { HelperAttribute attr = Attribute.GetCustomAttribute(mi,typeof(HelperAttribute)) as HelperAttribute; if(attr == null) {Console.WriteLine("No Help for {0}.",mi);} else { Console.WriteLine("Help for {0}:",mi); Console.WriteLine(" Url={0},Topic={1}",attr.Url,attr.Topic); } } } }
运行结果
第二篇预告
Attribute (二) 将谈Attribute在设计中的用途,拦截器、Builder 模式
本文完