前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Attribute基本介绍

Attribute基本介绍

作者头像
郑小超.
发布2018-01-26 15:38:21
7290
发布2018-01-26 15:38:21
举报
文章被收录于专栏:GreenLeavesGreenLeaves

一、基础知识点

1、什么是Attribute?

MSDN:公共语言运行时允许你添加类似关键字的说明,叫做Attribute,它可以对程序中的元素进行标注,如类型、字段、方法和属性等.Attributes和Microsoft .NET Framework文件的元数据保存在一起,可以用来向运行时描述你的代码,或者在程序运行的时候影响应用程序的行为。在.NET中,Attribute被用来处理多种问题,比如序列化、程序的安全特征、防止即时编译器对程序代码进行优化从而代码容易调试等等.

2、Attribute作为编译器的指令

Attribute作为编译器的指令数量不受限制,大致有以下三个Attribute:

(1)、Conditional:起条件编译的作用,只有满足条件,才允许编译器对它描述的代码进行编译。一般在程序调试时使用。

代码语言:javascript
复制
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中定义

代码语言:javascript
复制
static void Main(string[] args)
{
    int result=Test(1, 2);
    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:这个属性用来标记当前的方法已经被弃用,不再使用了。

代码语言:javascript
复制
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限定施加元素的类型,代码形式如下:

代码语言:javascript
复制
[AttributeUsage(参数设置)]
public class TestAttribute:Attribute
{
    //方法体
}

非常有意思的是AttributeUsage也是一个Attribute,这个是专门施加在Attribute上的Attribute,AttributeUsage自然也是从Attribute派生而来的,它有一个带参数的构造器,这个参数是AttributeTargets的枚举类型

代码语言:javascript
复制
[Serializable, ComVisible(true), Flags, __DynamicallyInvokable]
public enum AttributeTargets
{
   All=16383,
   Assembly=1,
   Module=2,
   Class=4,
   Struct=8,
   Enum=16,
   Constructor=32,
   Method=64,
   Property=128,
   Field=256,
   Event=512,
   Interface=1024,
   Parameter=2048,
   Delegate=4096,
   ReturnValue=8192
}     

注意:Flags特性,说明作为参数的AttributeTarges的值允许通过“|”操作来进行多个值得组合。如果你没有指定参数,那么默认参数就是All

除了AttributeTarges参数外,AttributeTarges还允许传入另外两个参数:

AllowMultiple: 读取或者设置这个属性,表示是否可以对一个程序元素施加多个Attribute 。

Inherited:读取或者设置这个属性,表示是否施加的Attribute 可以被派生类继承或者重载。

(4)、AttributeUsage的使用例子

代码语言:javascript
复制
    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描述一个类的检查信息

代码语言:javascript
复制
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编程中的应用(一)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-06-12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云代码分析
腾讯云代码分析(内部代号CodeDog)是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是持续跟踪分析代码,观测项目代码质量,支撑团队传承代码文化。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档