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

    1 神马是特性?如何自定义一个特性?

    (1)特性是什么

        特性是一个对象,可以加载到程序集及程序集的对象中,这些对象包括 程序集本身、模块、类、接口、结构、构造函数、方法、方法参数等,加载了特性的对象称作特性的目标。特性是为程序添加元数据(描述数据的数据)的一种机制,通过它可以给编译器提供指示或者提供对数据的说明。

          Attributes和Microsoft .NET Framework文件的元数据保存在一起

         总结为:定制特性attribute,本质上是一个类,为目标元素提供关联附加信息并在运行期以反射的方式来获取。

    几个习惯用法:
        自定义特性必须直接或间接继承自System.Attribute类而且该类必须要有公有的构造函数;
        自定义特性应该有一个Attribute后缀,习惯约定(在调用中可以省略,会自动匹配);
        非抽象特性必须要有public访问权限;
        定制特性不会影响应用元素的任何功能,只是约定了该元素具有的特质;  

    1.1 System.ObsoleteAttribute 特性

    给旧SendMsg()方法加上Obsolete特性来告诉编译器这个方法已经过时,当编译器发现当程序中有地方在使用这个用Obsolete标记过的方法时,就会给出一个警告信息。

    1.2 特性的使用方法

    首先是有一对方括号“[]”,在左方括号“[”后紧跟特性的名称,比如Obsolete,随后是一个圆括号“()”。和普通的类不同,这个圆括号不光可以写入构造函数的参数,还可以给类的属性赋值。

     

    (2)如何自定义特性

    定义一个特性的本质就是定义一个继承自System.Attribute类的类型.

    [AttributeUsage(AttributeTargets.Class, AllowMutiple=true, Inherited=false)]
    public class RecordAttribute :Attribute { private string recordType; // 记录类型:更新/创建 private string author; // 作者 private DateTime date; // 更新/创建 日期 private string memo; // 备注 // 构造函数,构造函数的参数在特性中也称为“位置参数”。 public RecordAttribute(string recordType, string author, string date) { this.recordType = recordType; this.author = author; this.date = Convert.ToDateTime(date); } // 对于位置参数,通常只提供get访问器 public string RecordType { get { return recordType; } } public string Author { get { return author; } } public DateTime Date { get { return date; } } // 构建一个属性,在特性中也叫“命名参数” public string Memo { get { return memo; } set { memo = value; } } } [Record("更新", "Matthew", "2008-1-20", Memo = "修改 ToString()方法")] [Record("更新", "Jimmy", "2008-1-18")] [Record("创建", "张子阳", "2008-1-15")] public class DemoClass { public override string ToString() { return "This is a demo class"; } } class Program { static void Main(string[] args) { Type t = typeof(DemoClass); Console.WriteLine("下面列出应用于 {0} 的RecordAttribute属性:" , t); // 获取所有的RecordAttributes特性 object[] records = t.GetCustomAttributes(typeof(RecordAttribute), false); foreach (RecordAttribute record in records) { Console.WriteLine(" {0}", record); Console.WriteLine(" 类型:{0}", record.RecordType); Console.WriteLine(" 作者:{0}", record.Author); Console.WriteLine(" 日期:{0}", record.Date.ToShortDateString()); if(!String.IsNullOrEmpty(record.Memo)){ Console.WriteLine(" 备注:{0}",record.Memo); } } } } 下面列出应用于 AttributeDemo.DemoClass 的RecordAttribute属性: AttributeDemo.RecordAttribute 类型:更新 作者:Matthew 日期:2008-1-20 备注:修改 ToString()方法 AttributeDemo.RecordAttribute 类型:更新 作者:Jimmy 日期:2008-1-18 AttributeDemo.RecordAttribute 类型:创建 作者:张子阳 日期:2008-1-15

      参照obsolete特性,我们应该发现,它继承自Attribute类,这说明我们的RecordAttribute也应该继承自Attribute类。

         其次,我们发现在这个特性的定义上,又用了三个特性去描述它,只需要掌握 AttributeUsage就可以了。

                 AttributeTargets 是一个位标记(枚举),它定义了特性可以应用的类型和对象。可以使用按位或“|”来进行组合

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

                假如有一个类继承自我们的DemoClass,那么将RecordAttribute添加到DemoClass上时,其子类也会获得该特性。而当特性应用于一个方法,如果继承自该类的子类将这个方法覆盖,那么Inherited则用于说明是否子类方法是否继承这个特性。

      实际项目的例子

    namespace SC.Component.Utility
    {
        using System;
        
        [AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=false)]
        public sealed class APIMethodAttribute : Attribute
        {
            private string m_APIUrl;
            
            public APIMethodAttribute()
            {
            }
            
            public APIMethodAttribute(string apiUrl)
            {
                this.m_APIUrl = apiUrl;
            }
            
            public string APIUrl
            {
                get
                {
                    return this.m_APIUrl;
                }
                set
                {
                    this.m_APIUrl = value;
                }
            }
        }
    }
            [APIMethod("TravelOrderList")]
            public static string GetTravelList(JourneyCalendarParmas reqParams)
            {
                string result = string.Empty;
                try
                {
                    ........
                }
                catch (Exception ex)
                {                
                    return null;
                }
    
                return result;
            }
    

      

  • 相关阅读:
    金蝶 kis一些功能的内部逻辑和个人技巧
    mysql横向和纵向合并sql数据用于展示,快递导出导入海量数据
    laravel carbon时间处理组件开发文档-中文版
    金蝶kis数据库说明(转载)
    java微信支付,对账单下载
    RabbitMQ中文文档PHP版本(七)--发布者确认
    RabbitMQ中文文档PHP版本(六)--远程过程调用(RPC)
    RabbitMQ中文文档PHP版本(五)--主题
    RabbitMQ中文文档PHP版本(四)--路由
    RabbitMQ中文文档PHP版本(二)--发布/订阅
  • 原文地址:https://www.cnblogs.com/tiantianle/p/5768075.html
Copyright © 2011-2022 走看看