Attribute基本介绍
一、基础知识点
1、什么是Attribute?
MSDN:公共语言运行时允许你添加类似关键字的说明,叫做Attribute,它可以对程序中的元素进行标注,如类型、字段、方法和属性等.Attributes和Microsoft .NET Framework文件的元数据保存在一起,可以用来向运行时描述你的代码,或者在程序运行的时候影响应用程序的行为。在.NET中,Attribute被用来处理多种问题,比如序列化、程序的安全特征、防止即时编译器对程序代码进行优化从而代码容易调试等等.
2、Attribute作为编译器的指令
Attribute作为编译器的指令数量不受限制,大致有以下三个Attribute:
(1)、Conditional:起条件编译的作用,只有满足条件,才允许编译器对它描述的代码进行编译。一般在程序调试时使用。
static void Main(string[] args)
{
DisplayRunningMessage();
Console.ReadKey();
}
[Conditional("DEBUG")]
static void DisplayRunningMessage()
{
Console.WriteLine("开始运行Main子程序。当前时间是"+DateTime.Now);
}
Conditional对满足参数的定义条件的代码进行编译,如果没有定义DEBUG,那么该方法将不被编译,读者可以把#define DEBUG一行注释掉看看输出的结果(release版本,在Debug版本中Conditional的debug总是成立的)
(2)、DllImport:用来标记非.Net的函数,表明该方法在一个外部的Dll中定义
static void Main(string[] args)
{
int result=Test(, );
Console.WriteLine("Result is {0}", result);
Console.ReadKey();
}
[DllImport("ClassLibrary1.dll")]
public static extern int Test(int a,int b);
DllImport用于调用C或者C++等外部的dll程序集,其修饰的方法必须是外部程序集的主入口。
(3)、Obsolete:这个属性用来标记当前的方法已经被弃用,不再使用了。
static void Main(string[] args)
{
OldMethod();
NewMethod();
Console.ReadKey();
}
static void NewMethod()
{
Console.WriteLine("I'am new Method");
} [Obsolete]
static void OldMethod()
{
Console.WriteLine("I'am old Method");
}
3、自定义Attribute类
除了.NET提供的那些Attribute派生类之外,我们可以自定义我们自己的Attribute,所有自定义的Attribute必须从Attribute类派生。下面来简单说明下Attribute类:
(1)、Attribute类基本知识点
protected Attribute(): 保护的构造器,只能被Attribute的派生类调用。
static Attribute GetCustomAttribute():这个方法有8种重载的版本,它被用来取出施加在类成员上指定类型的Attribute。
static Attribute[] GetCustomAttributes(): 这个方法有16种重载版本,用来取出施加在类成员上指定类型的Attribute数组。
static bool IsDefined():由八种重载版本,看是否指定类型的定制attribute被施加到类的成员上面。
bool IsDefaultAttribute(): 如果Attribute的值是默认的值,那么返回true。
bool Match():表明这个Attribute实例是否等于一个指定的对象。
公共属性: TypeId: 得到一个唯一的标识,这个标识被用来区分同一个Attribute的不同实例。
上面是Attribute的基本知识点,想要了解详细的信息,请使用Reflector查看源代码;
(2)、自定义Attribute类命名规则
命名规则:Attribute的类名+"Attribute",当你的Attribute施加到一个程序的元素上的时候,编译器先查找你的Attribute的定义,如果没有找到,那么它就会查找“Attribute名称"+Attribute的定义。如果都没有找到,那么编译器就报错。 ---如TestAttribute
(3)、给自定义Attribute限定施加的元素的类型 ---AttributeUsage
通过AttributeUsage来给我们自定义的Attribute限定施加元素的类型,代码形式如下:
[AttributeUsage(参数设置)]
public class TestAttribute:Attribute
{
//方法体
}
非常有意思的是AttributeUsage也是一个Attribute,这个是专门施加在Attribute上的Attribute,AttributeUsage自然也是从Attribute派生而来的,它有一个带参数的构造器,这个参数是AttributeTargets的枚举类型
[Serializable, ComVisible(true), Flags, __DynamicallyInvokable]
public enum AttributeTargets
{
All=,
Assembly=,
Module=,
Class=,
Struct=,
Enum=,
Constructor=,
Method=,
Property=,
Field=,
Event=,
Interface=,
Parameter=,
Delegate=,
ReturnValue=
}
注意:Flags特性,说明作为参数的AttributeTarges的值允许通过“|”操作来进行多个值得组合。如果你没有指定参数,那么默认参数就是All
除了AttributeTarges参数外,AttributeTarges还允许传入另外两个参数:
AllowMultiple: 读取或者设置这个属性,表示是否可以对一个程序元素施加多个Attribute 。
Inherited:读取或者设置这个属性,表示是否施加的Attribute 可以被派生类继承或者重载。
(4)、AttributeUsage的使用例子
class Program
{
static void Main(string[] args)
{
} [Test]
static void TestMethod()
{ }
} /// <summary>
/// 通过AttributeUsage设置Test属性只对类有效
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class TestAttribute:Attribute
{ }
上面定义了一个Test属性,并通过AttributeUsage设置该属性只对类有效,但是Program类中却用它修饰方法,所以程序报错,抱错信息如下:
二、Attribute高级应用
1、描述一个单元类的检查信息
通过Attribute描述一个类的检查信息
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks; namespace ConsoleApplication1
{ class Program
{
static void Main(string[] args)
{
System.Reflection.MemberInfo info = typeof(BeCheckedClass);//通过反射获取BeCheckedClass类
//根据反射获取BeCheckedClass类通过Attribute.GetCustomAttribute来获取描述它的特性
CodeReviewAttribute attri = (CodeReviewAttribute)Attribute.GetCustomAttribute(info, typeof(CodeReviewAttribute));
if(!object.ReferenceEquals(attri,null))
{
Console.WriteLine("代码检查人:{0}", attri.Reviewer);
Console.WriteLine("检查时间:{0}", attri.Date);
Console.WriteLine("备注:{0}", attri.Comment);
Console.ReadKey();
}
} }
[CodeReviewAttribute("小超", "2017-6-12", Comment = "检查通过")]
public class BeCheckedClass
{ } /// <summary>
/// 代码检查属性
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class CodeReviewAttribute: Attribute
{
private string _reviewer; //代码检查人
private string _date; //检查日期
private string _comment; //检查结果信息
public CodeReviewAttribute(string reviewer,string date)
{
this._reviewer = reviewer;
this._date = date;
} public string Reviewer
{
get
{
return _reviewer;
}
}
public string Date
{
get
{
return _date;
}
}
public string Comment
{
get
{
return _comment;
}
set
{
_comment = value;
}
}
}
}
通过反射获取BeCheckedClass类,在通过Attribute.GetCustomAttribute获取BeCheckedClass类的描述特性值,从而实现这个功能!
最新文章
- UI控件(UISlider)
- 机器学习 1 regression
- Centos5, 6下更改系统时间和时区
- 加载 CSS 时不影响页面渲染
- Studio for WPF:使用 C1TileView 创建图片库
- poj 1742 Coins (动态规划,背包问题)
- PySpark调用自定义jar包
- windows不能在本地计算机启动apache
- RedHat 6.5 离线安装 apache2.4.23
- 自己在安装centos 系统时, 是使用英文安装 成功,现在系统语言为英语,如何设置为中文?
- IOS设计模式学习(19)策略
- ORACLE SEQUENCE用法 (自增长)
- sql 中的 indexOf 与 lastIndexOf
- imagemagick /tmp/magick-xxxxxxxx
- hdu_2243_考研路茫茫——单词情结(AC自动机+矩阵)
- 关于Ajax的type为post提交方式出现请求失效问题
- Kong(V1.0.2)Network &; Firewall
- pygame-KidsCanCode系列jumpy-part12-platform图片
- Unity3d外部加载音频,视频,图片等资源 及根据路径获取制定格式的文件
- linux 磁盘空间被占满但找不到目标文件的问题处理 lsof命令