一、基础知识点

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编程中的应用(一)

Attribute基本介绍的更多相关文章

  1. [C#]Attribute特性(2)——方法的特性及特性参数

    上篇博文[C#]Attribute特性介绍了特性的定义,类的特性,字段的特性,这篇博文将介绍方法的特性及特性参数相关概念. 3.方法的特性 之所以将这部分单列出来进行讨论,是因为对方法的特性查询的反射 ...

  2. CallerInformation

    http://www.cnblogs.com/henryzhu/archive/2013/01/27/csharp-5-new-callerinformation.html 去年8月,Visual S ...

  3. Object C学习笔记3-对象的使用和定义

    1. 如何定义一个对象 在面向对象的语言中,定义一个对象是使用Class关键字,而在Object-C中则是使用@interface,@interface用于定义对象的属性和方法,@implementa ...

  4. crmsh语法

    .查看配置信息 crm(live)# configure crm(live)configure# show node node1 node node2 property cib-bootstrap-o ...

  5. OAF_开发系列06_实现OAF属性集的介绍和开发Attribute Set(案例)

    20150705 Created By BaoXinjian

  6. C# 特性(Attribute)详细介绍

    1.什么是Atrribute 首先,我们肯定Attribute是一个类,下面是msdn文档对它的描述:公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注 ...

  7. (转)C# 特性(Attribute)详细介绍

    本文转载自:http://www.cnblogs.com/luckdv/articles/1682488.html 1.什么是Atrribute 首先,我们肯定Attribute是一个类,下面是msd ...

  8. .Net内置特性Attribute介绍

    特性Attribute概述 特性(Attribute)是一种特殊的类型,可以加载到程序集或者程序集的类型上,这些类型包括模块.类.接口.结构.构造函数.方法.字段等,加载了特性的类型称之为特性的目标. ...

  9. C#中Attribute介绍

    什么是特性? MSDN中定义为:公共语言运行时运行添加类似关键字的描述声明,叫做Attribute,它对程序中的元素进行标注,如类型.方法.字段和属性等.attribute和Microsoft.Net ...

随机推荐

  1. UVa 1151 Buy or Build (最小生成树+二进制法暴力求解)

    题意:给定n个点,你的任务是让它们都连通.你可以新建一些边,费用等于两点距离的平方(当然越小越好),另外还有几种“套餐”,可以购买,你购买的话,那么有些边就可以连接起来, 每个“套餐”,也是要花费的, ...

  2. cin和gitchar的区别

    cin是iostream(输入输出类) 类下的istream(输入类)类的对象,作用是顺序输入字符串.cin.get()是cin的方法.cin.get()是C++面向对象的操作,getchar()是C ...

  3. linux计划任务(一)

    一次性计划任务 at /etc/init.d/atd [root@localhost ~]# at : at> /bin/ls /etc |wc -l > /tmp/yimiao_demo ...

  4. iphone在微信中audio 音频无法自动播放

    问题: Html5的audio 音频在电脑端和android端都可以实现自动播放,在iphone上无法实现,下面针对的是微信浏览器里面的解决方法 html代码: <div id="au ...

  5. POJ2031 Building a Space Station 2017-04-13 11:38 48人阅读 评论(0) 收藏

    Building a Space Station Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 8572   Accepte ...

  6. java并发编程实战:第八章----线程池的使用

    一.在任务和执行策略之间隐性耦合 Executor框架将任务的提交和它的执行策略解耦开来.虽然Executor框架为制定和修改执行策略提供了相当大的灵活性,但并非所有的任务都能适用所有的执行策略. 依 ...

  7. Java enum枚举类型

    java的枚举类型详解: 简单示例: public enum Color{ RED,BLUE,BLACK,YELLOW,GREEN } 复杂示例(带自定义构造方法与类型) public enum En ...

  8. Zero Clipboard js+swf实现的复制功能使用方法

    开发中经常会用到复制的功能,在 IE 下实现比较简单.但要想做到跨浏览器比较困难了.本文将介绍一个跨浏览器的库类 Zero Clipboard .它利用 Flash 进行复制,所以只要浏览器装有 Fl ...

  9. system.data.oracleclient 需要 8.17 需要oracle客户端问题

    1.下载 2.程序引用   Oracle.DataAccess.dll  其他引用放在debug下

  10. django drf django-filter的method过滤

    1.View Demo from django.shortcuts import render from rest_framework.views import APIView from rest_f ...