zoukankan      html  css  js  c++  java
  • .NET基础 (18)特性

    特性
    1 什么是特性,如何自定义一个特性
    2 .NET中特性可以在哪些元素上使用
    3 有哪几种方法可以获知一个元素是否申明某个特性
    4 一个元素是否可以重复申明同一个特性

    特性
    1 什么是特性,如何自定义一个特性

    特性是一种特殊的用以申明式编程的机制,特性类型是一族继承自System.Attribute的类型,在编译时,特性的使用会被写入元数据中,以共运行或者程序中的反射使用。自定义一个特性,本质上是定义一个继承自System.Attribute的类型。

    自定义特性示例:

        /// <summary>
        /// 自定义的特性
        /// </summary>
        [AttributeUsage(AttributeTargets.Class)]
        public class MyAttribute : Attribute
        {
            private String _classname;
            public MyAttribute(String s)
            {
                _classname = s;
            }
            //一个只读属性
            public String ClassName
            {
                get
                {
                    return _classname;
                }
            }
        }
    
        /// <summary>
        /// 使用自定义属性
        /// </summary>
        [MyAttribute("UseMyAttribute")]
        class UseMyAttribute
        {
            static void Main(string[] args)
            {
                Type t = typeof(UseMyAttribute);
                Object[] attributes = t.GetCustomAttributes(false);
                MyAttribute att = (MyAttribute)attributes[0];
                Console.WriteLine(att.ClassName);
                Console.Read();
            }
        }

    输出:

    UseMyAttribute

    特性将被写入元数据中,所以特性的使用基本都基于反射机制。

    有几点需要注意:

    • 按照惯例,特性的名字都以Attribute结尾。
    • C#中,为了使用方便,可以省略特性名字后缀Attribute,如 [MyAttribute("UseMyAttribute")] 可写为 [My("UseMyAttribute")]。
    • 特性自身可以添加其他特性。


    2 .NET中特性可以在哪些元素上使用

    特性可以应用在程序集、模块、结构、枚举、构造方法、方法、属性、字段、事件、接口、参数、委托、返回参数和泛型参数这些目标元素上。通过AttributeUsage特性可以限制自定义特性的使用范围。

    示例:

    using System;
    
    //应用在程序集上
    [assembly: MyAttribute]
    //应用在模块上
    [module: MyAttribute]
    
    //应用在类型上
    [type: MyAttribute]
    class AttributeTargets<[typevar: MyAttribute] T> //泛型参数上
    {
        //应用在字段上
        [field: MyAttribute]
        private String _MyString;
    
        //应用在构造方法上
        [method: MyAttribute]
        public AttributeTargets()
        {
        }
    
        //应用在属性上
        [property: MyAttribute]
        public String MyString
        {
            get
            {
                return _MyString;
            }
        }
    
        //应用在方法上
        [return: MyAttribute]
        public String Format(
            //应用在方法参数上
            [param: MyAttribute]String f)
        {
            return null;
        }
    
        //应用在事件上
        [event: MyAttribute]
        public event EventHandler MyEvent;
    }
    
    /// <summary>
    /// 一个空的特性
    /// 可用于所有元素
    /// </summary>
    public class MyAttribute : System.Attribute
    {
    }
    
    public class MainClass
    {
        static void Main(string[] args)
        {
        }
    }


    3 有哪几种方法可以获知一个元素是否申明某个特性

    System.Attribute.IsDefined

    System.Attribute.GetCustomAttribute

    System.Attribute.GetCustomAttributes

    System.Reflection.CustomAttributeData

    示例:

        [My("GetAttributes")]
        class GetAttributes
        {
            static void Main(string[] args)
            {
                Type attributeType = typeof(MyAttribute);
                Type thisClass = typeof(GetAttributes);
    
                //使用IsDefined方法
                bool defined = Attribute.IsDefined(
                            thisClass,
                            attributeType);
                Console.WriteLine(
                     "GetAttributes类型是否申明了MyAttribute特性:{0}",
                     defined.ToString());
    
                //使用Attribute.GetCustomAttribute方法
                Attribute att = Attribute.GetCustomAttribute(
                            thisClass,
                            attributeType);
                if (att != null)
                {
                    Console.WriteLine(
                        "GetAttributes类型申明了MyAttribute特性。");
                    Console.WriteLine("名字为:{0}",
                         ((MyAttribute)att).Name);
                }
    
                //使用Attribute.GetCustomAttributes方法
                Attribute[] atts = Attribute.GetCustomAttributes(
                                thisClass,
                                attributeType);
                if (atts.Length > 0)
                {
                    Console.WriteLine(
                         "GetAttributes类型申明了MyAttribute特性。");
                    Console.WriteLine("名字为:{0}",
                         ((MyAttribute)atts[0]).Name);
                }
    
                //使用System.Reflection.CustomAttributeData类型
                IList<CustomAttributeData> list =
                    CustomAttributeData.GetCustomAttributes(thisClass);
                if (list.Count > 0)
                {
                    Console.WriteLine(
                         "GetAttributes类型申明了MyAttribute特性。");
                    //注意这里可以对特性进行分析,但不能得到其实例
                    CustomAttributeData attdata = list[0];
                    Console.WriteLine("特性的名字是:{0}",
                          attdata.Constructor.DeclaringType.Name);
                    Console.WriteLine("特性的构造方法有{0}个参数。",
                        attdata.ConstructorArguments.Count);
                }
                Console.Read();
            }
        }
    
        /// <summary>
        /// 一个简单的特性
        /// </summary>
        [AttributeUsage(AttributeTargets.All)]
        public sealed class MyAttribute : Attribute
        {
            private String _name;
            public MyAttribute(String s)
            {
                _name = s;
            }
            public String Name
            {
                get
                {
                    return _name;
                }
            }
        }

    输出:

    GetAttributes类型是否申明了MyAttribute特性:True
    GetAttributes类型申明了MyAttribute特性。
    名字为:GetAttributes
    GetAttributes类型申明了MyAttribute特性。
    名字为:GetAttributes
    GetAttributes类型申明了MyAttribute特性。
    特性的名字是:MyAttribute
    特性的构造方法有1个参数。

    4 一个元素是否可以重复申明同一个特性

    当一个特性申明了AttributeUsage特性并且显示地将AllowMultiple属性设置为true时,该特性就可以在同一元素上多次申明,否则的话编译器将被报错。

    示例:

        [My("Class1")]
        [My("Class2")]
        [My("Class1")]
        class AllowMultiple
        {
            static void Main(string[] args)
            {
            }
        }
    
        /// <summary>
        /// 使用AttributeUsage限定使用范围
        /// 并且允许在同一元素上多次申明
        /// </summary>
        [AttributeUsage(AttributeTargets.Class,AllowMultiple=true)]
        class MyAttribute : Attribute
        {
            private String _s;
    
            public MyAttribute(String s)
            {
                _s = s;
            }
        }

    转载请注明出处:

    作者:JesseLZJ
    出处:http://jesselzj.cnblogs.com

  • 相关阅读:
    图片上下左右居中
    点击滚动指定高度 屏幕滚动事件
    实例16 验证登录信息的合法性
    实例15 判断某一年是否为闰年
    实例14 实现两个变量的互换(不借助第3个变量)
    实例13 不用乘法运算符实现2*16
    实例12 用三元运算符判断奇数和偶数
    实例11 加密可以这样简单(位运算)
    实例10 自动类型转换与强制类型转换
    实例9 重定向输入流实现程序日志
  • 原文地址:https://www.cnblogs.com/jesselzj/p/4802413.html
Copyright © 2011-2022 走看看