zoukankan      html  css  js  c++  java
  • 特性Attribute

    1.Attribute介绍   

    我们用VS进行编程时,智能提示再提供方法和属性列表的时候,有时会有下面的这种情况:

    提示某个方法已经是过时的了,还会给与提示信息。出现此效果就是Attribute(特性)的功劳了。    特性是一种特殊的类型,可以加载到程序集或者程序集中的类型上,这些类型包括模块、类、接口、结构、构造函数、方法、方法参数等,加载了特性的类型称作特性的目标。特性是为程序集添加元数据(描述数据的数据)的一种机制,通过它可以为编译器提供指示或者对数据的说明。

    2.Attribute的使用

        Attribute在特性目标上使用构成如下图:

    []后紧跟的就是Attribute的名称,()内可以传递构造函数需要传进的参数以及给属性赋值的参数。下面是obsoleteAttribute的定义

    // 摘要:
        //     标记不再使用的程序元素。无法继承此类。
        [Serializable]
        [ComVisible(true)]
        [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
        public sealed class ObsoleteAttribute : Attribute
        {
            // 摘要:
            //     使用默认属性初始化 System.ObsoleteAttribute 类的新实例。
            public ObsoleteAttribute();
            //
            // 摘要:
            //     使用指定的变通方法消息初始化 System.ObsoleteAttribute 类的新实例。
            //
            // 参数:
            //   message:
            //     描述可选的变通方法的文本字符串。
            public ObsoleteAttribute(string message);
            //
            // 摘要:
            //     使用变通方法消息和布尔值初始化 System.ObsoleteAttribute 类的新实例,该布尔值指示是否将使用已过时的元素视为错误。
            //
            // 参数:
            //   message:
            //     描述可选的变通方法的文本字符串。
            //
            //   error:
            //     指示是否将使用已过时的元素视为错误的布尔值。
            public ObsoleteAttribute(string message, bool error);
    
            // 摘要:
            //     获取指示编译器是否将使用已过时的程序元素视为错误的布尔值。
            //
            // 返回结果:
            //     如果将使用已过时的元素视为错误,则为 true;否则为 false。默认为 false。
            public bool IsError { get; }
            //
            // 摘要:
            //     获取变通方法消息,包括对可选程序元素的说明。
            //
            // 返回结果:
            //     变通方法文本字符串。
            public string Message { get; }
        }

    特性目标应用了特性后,编译时会提示

     

    3.自定义Attribute

       仿照Obsolete属性,可以自己定义一个Attribute。自定义的Attribute就是个普通的类,只是实现了Attribute抽象类。不管是构造函数的参数还是属性,全部写到构造函数的圆括号中,对于构造函数的参数,必须采取构造函数参数的顺序和类型,因此叫做位置参
    数;对于属性,采用“属性=值”这样的格式,它们之间用逗号分隔,称作命名参数。命名参数是可选择输入的。

       AttributeUsage特性的构造函数接受一个AttributeTargets类型的参数,它定义了特性可以应用的类型,AttributeTargets也是一个位标记。

       

     // 摘要: 
        //     指定可以对它们应用特性的应用程序元素。
        [Serializable]
        [ComVisible(true)]
        [Flags]
        public enum AttributeTargets
        {
            // 摘要: 
            //     可以对程序集应用属性。
            Assembly = 1,
            //
            // 摘要: 
            //     可以对模块应用属性。
            Module = 2,
            //
            // 摘要: 
            //     可以对类应用属性。
            Class = 4,
            //
            // 摘要: 
            //     可以对结构应用属性,即值类型。
            Struct = 8,
            //
            // 摘要: 
            //     可以对枚举应用属性。
            Enum = 16,
            //
            // 摘要: 
            //     可以对构造函数应用属性。
            Constructor = 32,
            //
            // 摘要: 
            //     可以对方法应用属性。
            Method = 64,
            //
            // 摘要: 
            //     可以对属性 (Property) 应用属性 (Attribute)。
            Property = 128,
            //
            // 摘要: 
            //     可以对字段应用属性。
            Field = 256,
            //
            // 摘要: 
            //     可以对事件应用属性。
            Event = 512,
            //
            // 摘要: 
            //     可以对接口应用属性。
            Interface = 1024,
            //
            // 摘要: 
            //     可以对参数应用属性。
            Parameter = 2048,
            //
            // 摘要: 
            //     可以对委托应用属性。
            Delegate = 4096,
            //
            // 摘要: 
            //     可以对返回值应用属性。
            ReturnValue = 8192,
            //
            // 摘要: 
            //     可以对泛型参数应用属性。
            GenericParameter = 16384,
            //
            // 摘要: 
            //     可以对任何应用程序元素应用属性。
            All = 32767,
        }

    AllowMutiple属性用于设置该特性是不是可以重复地添加到一个类型上(默认为false),如下:

        [My("messageOne",OtherInfo = "OtherInfoOne")]
        [My("messageTwo",OtherInfo = "OtherInfoTwo")]
        public class DemoClass
        {
          //todo:
        }

    如果将Inherited设置为True,当有一个类继承自FatherClass时,则FatherClass的子类也会获得该特性。而当将特性应用于一个方法,如果继承自该类的子类覆盖了这个方法,那么子类中的方法也将继承这个特性,一般我们设置为false。

    则自定义的属性代码如下:

    [AttributeUsage(AttributeTargets.All,AllowMultiple = true,Inherited = false)]
        public class MyAttribute : Attribute
        {
            private string message;//位置参数
    
            public MyAttribute(string msg)
            {
                this.message = msg;
            }
    
            public string Message 
            {
                get
                {
                    return message;
                    
                }
            }
            public string OtherInfo { get; set; }//命名参数
        }

    使用方式同普通的Attribute。

    4.反射查看自定义的Attribute

       可以通过Type.GetCustomerAttributes获取到对象所使用自定义得属性,当指定GetCustomAttributes() 方法的第一个参数attributeType时,将只返回该类型的特性,否则将返回全部特性示例代码如下:

    public class Program
        {
            static void Main(string[] args)
            {
                Type t = typeof (DemoClass);
                object[] allAttributes = t.GetCustomAttributes(typeof (MyAttribute), false);//获取所有自定义特性
                foreach (MyAttribute myAttribute in allAttributes)
                {
                    Console.WriteLine("Message:"+myAttribute.Message+"    OtherInfo:"+myAttribute.OtherInfo+"
    ");
                }
                Console.ReadKey();
            }
        }

    执行的结果为:

  • 相关阅读:
    Writing a progress/status report
    五月
    MEGVII 旷视 Brain++ 平台;天元MegEngine 平台简要分析
    地平线4闪退解决办法;地平线4一启动闪退;Forza Horizon 4 won't start
    [已解决]Adobe Reader中禁用“保存更改”对话框;Adobe pdf 要在关闭前保存更改; 另存为;
    想写点新的东西
    IO测试工具:vdbench
    CUDA 线程ID 计算方式;NVIDIA GPGPU;
    csgo 黑屏闪退,解决方法;
    Simulator 和 Emulator 的相同和不同;
  • 原文地址:https://www.cnblogs.com/yanglaosan/p/6687460.html
Copyright © 2011-2022 走看看