zoukankan      html  css  js  c++  java
  • 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(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:这个属性用来标记当前的方法已经被弃用,不再使用了。

    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=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的使用例子

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

  • 相关阅读:
    redis 数据类型详解 以及 redis适用场景场合
    angular.js记录
    Python chr() 函数
    Python frozenset() 函数
    Python 字典 dict() 函数
    Python set() 函数
    Python tuple 函数
    Python eval() 函数
    Python repr() 函数
    Python str() 函数
  • 原文地址:https://www.cnblogs.com/GreenLeaves/p/6993538.html
Copyright © 2011-2022 走看看