• C#秘密武器之特性


    一、概述

    Attribute说白了就是一个类而已,里边一般含有一些附加信息,或者一些特殊的处理逻辑,以便告诉编译器应用该特性的东东是个奇葩,需要特殊对待!

    二、使用时的注意事项

    2.1. Attribute是一个类,必须继承自System.Attribute

    2.2 Attribute命名规范
    Attribute命名一般以Attribute结尾, 但是在具体使用时候,可以省去Attribute这一后缀。加入定义了一个HelperAttribute, 具体使用的时候,可以这样写[Helper].

    2.3 Attribute的使用限制
    Attribute类在定义的时候,可以指定这个Attribute的应用范围,AttributeTargets枚举就列出了可以指定的范围,可以是class, field等;AllowMutiple为true或者false,意思就是是否让该特性在某个地方重复使用(比如在某一个类上使用多次);Inherited为true或者false,意思就是该特性是否会被应用该特性的类的子类继承。

    2.4 Attribute中的参数赋值

    位置参数(Attribute构造函数的参数):必填,且顺序要一致!

    命名参数(Attribute中的其他字段或者属性):在使用时可以省略!

    三、自定义一个Attribute并读取其值

    举个栗子:

    [AttributeUsage(AttributeTargets.Class, AllowMutiple=true, Inherited=false)]
     public class BookAttribute:Attribute
        {
            
    public string Msg { get; set; }
            
    public double Version = 1.0;
            
    public MyFirstAttribute(string msg)
             {
                 Msg
    = msg;
             }
        }

    通过反射获取Attribute相关信息:

    namespace TestAttribute
      {
    //多次使用特性类

    [Book("人民邮电")] [Book("北京")]   class BookInfo   {    public string bookinfo = "图书信息";    //构造函数   public BookInfo()   {   }   }   }
    static void Main(string[] args)
            {
                BookInfo bookinfo = new BookInfo();
                MemberInfo typeinfo = typeof(BookInfo);
              object[] bookarr= typeinfo.GetCustomAttributes(typeof(BookAttribute), false);
          if (bookarr.GetLength(0) != 0)
                {
                    BookAttribute bookattribute1 = (BookAttribute)bookarr[0];
                      BookAttribute bookattribute2 = (BookAttribute)bookarr[1];
                      Console.WriteLine(bookinfo.bookinfo);
                    Console.WriteLine("出版社为:" + bookattribute1.Msg+ "城市为:" + bookattribute2.Msg);
                    Console.ReadKey();
                }
            }

    四、学会使用一些.NET内置特性

    举个栗子:

    System.ObsoleteAttribute:告诉编译器某个方法已经过时,然后当编译器发现程序中有地方在使用这个用Obsolete标记过的方法时,就会给出一个警告信息。

    public class TestClass
    {
    // 添加Obsolete特性
    [Obsolete("请使用新的SendMsg(Message msg)重载方法")]
    public static void ShowMsg()
    {
    Console.WriteLine("这是旧的SendMsg()方法");
    }
    }
    private void button1_Click(object sender, EventArgs e)
    {
    TestClass.ShowMsg();
    }

    现在运行这段代码,我们会发现编译器给出了一个警告!

    五、特性在枚举上的应用

    enum Gender
    {
           [Description(“男”)]
           Man,
    
           [Description(“女”)]
           Woman
    };
    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
    using System.Reflection;  
       
    namespace MyTools  
    {  
        /// <summary>   
        /// 枚举帮助类   
        /// </summary>   
       public static class EnumHelper  
        {  
           /// <summary>   
           /// 获取枚举项的Attribute   
           /// </summary>   
           /// <typeparam name="T">自定义的Attribute</typeparam>   
          /// <param name="source">枚举</param>   
          /// <returns>返回枚举,否则返回null</returns>   
           public static T GetCustomAttribute<T>(Enum source) where T : Attribute  
           {  
               Type sourceType = source.GetType();  
               string sourceName = Enum.GetName(sourceType, source);  
               FieldInfo field = sourceType.GetField(sourceName);  
               object[] attributes = field.GetCustomAttributes(typeof(T), false);  
               foreach (object attribute in attributes)  
               {  
                  if (attribute is T)  
                       return (T)attribute;  
               }  
              return null;  
           }  
       
            /// <summary>   
           ///获取DescriptionAttribute描述   
           /// </summary>   
           /// <param name="source">枚举</param>   
           /// <returns>有description标记,返回标记描述,否则返回null</returns>   
            public static string GetDescription(this Enum source)  
            {  
               var attr = GetCustomAttribute<System.ComponentModel.DescriptionAttribute>(source);  
               if (attr == null)  
                  return null;  
       
               return attr.Description;  
            }
    
            public static EnumT GetValueByDescription<EnumT>(string description)
            {
                var type = typeof(EnumT);
                if (!type.IsEnum)
                    throw new ArgumentException("This method is destinated for enum types only.");
                foreach (var enumName in Enum.GetNames(type))
                {
                    var enumValue = Enum.Parse(type, enumName);
                    if (description == ((Enum)enumValue).GetDescription())
                        return (EnumType)enumValue;
                }
                throw new ArgumentException("There is no value with this description among specified enum type values.");
            }
      
       }  
    }  

    使用方法:

    Gender.Man.GetDescription()

    注意MVC中特性的巧妙应用,改写!

  • 相关阅读:
    VMwarePro密钥
    Windows事件ID
    python中安装下载超时,下载不了安装包
    PNG文件结构分析 ---Png解析
    世界协调时间(UTC)与中国标准时间
    计算机用户权限比较
    pikachu-xx型注入
    pikachu-搜索型注入 #手工注入
    显示桌面图标
    SQL2005 数据库还原到 SQL2008 错误 3145 解决办法
  • 原文地址:https://www.cnblogs.com/WeiGe/p/4207475.html
Copyright © 2020-2023  润新知