一、基础知识点

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类的描述特性值,从而实现这个功能!

本文参考自Attribute在.net编程中的应用(一)

最新文章

  1. UI控件(UISlider)
  2. 机器学习 1 regression
  3. Centos5, 6下更改系统时间和时区
  4. 加载 CSS 时不影响页面渲染
  5. Studio for WPF:使用 C1TileView 创建图片库
  6. poj 1742 Coins (动态规划,背包问题)
  7. PySpark调用自定义jar包
  8. windows不能在本地计算机启动apache
  9. RedHat 6.5 离线安装 apache2.4.23
  10. 自己在安装centos 系统时, 是使用英文安装 成功,现在系统语言为英语,如何设置为中文?
  11. IOS设计模式学习(19)策略
  12. ORACLE SEQUENCE用法 (自增长)
  13. sql 中的 indexOf 与 lastIndexOf
  14. imagemagick /tmp/magick-xxxxxxxx
  15. hdu_2243_考研路茫茫——单词情结(AC自动机+矩阵)
  16. 关于Ajax的type为post提交方式出现请求失效问题
  17. Kong(V1.0.2)Network &amp; Firewall
  18. pygame-KidsCanCode系列jumpy-part12-platform图片
  19. Unity3d外部加载音频,视频,图片等资源 及根据路径获取制定格式的文件
  20. linux 磁盘空间被占满但找不到目标文件的问题处理 lsof命令

热门文章

  1. Hadoop学习【一】单机版搭建
  2. (最小生成树)Eddy&#39;s picture -- hdu -- 1162
  3. 咏南中间件当作WEB SERVER使用方法
  4. css选择器与DOM&#39;匹配的关系
  5. EAS_AOP分布式事务
  6. C# winform无边框窗体移动
  7. EasyUI DataGrid 使用(分页,url数据获取,data转json)
  8. ES6——Symbol数据类型
  9. ASP.NET 页面执行顺序详解
  10. MVC中获取所有按钮,并绑定事件!