本文导读
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 模式
本文完