zoukankan      html  css  js  c++  java
  • c# 反射+Attribute 实现获取Description的两种做法

    直接看到代码,其中代码和文字描述都在里面;

    using System;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Threading.Tasks;
    
    //题目就是attribute 反射 中间缓存;
    
    //为啥缓存的key 是我们的type 类型呢?
    
    //首先会定义我们的一个基本的attribute属性,其实net中已经自带这个功能;
    
    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Enum)]
    public class PropertyDesc :Attribute
    {
    
        public string Desc { get; private set; }
    
        public PropertyDesc(string propertyDescription)
        {
            Desc = propertyDescription;
        }
    }
    
    //枚举数据类型的结构;
    public enum Product:byte
    {
    
        [PropertyDesc("电脑")]
        computer =1,
    
        [PropertyDesc("电视")]
        Tv =2
    
    }
    
    public class User
    {
        public string Name { get; set; }
    }
    
    //可以最终写成我们的额动态扩展的东西滴呀;
    //获取的是指定的类型的数据;
    
    public class enumHelper<T> where T:class
    {
    
        private static Dictionary<Type, Dictionary<string, string>> _cache = new Dictionary<Type, Dictionary<string, string>>();
    
    
        /// <summary>
        /// 这种做法不是特别完美,但是,效果还是比较好的;
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public static string GetEnumDescription(object p)
        {
            Type t = p.GetType();
            if (!_cache.ContainsKey(t))
            {
                GetAndSaveCacheEnumDescription<T>(t);
            }
            var dic = _cache[t];
            var fieldName = p.ToString();
            var result = dic.ContainsKey(fieldName)?dic[fieldName]:$"Can not find {fieldName} description";
            return result;
    
        }
    
        private static void GetAndSaveCacheEnumDescription<T>(Type t)
        {
            
            var fields = t.GetFields();  //一次性取出所有枚举字段;
            var dic = new Dictionary<string, string>();
            _cache.Add(t, dic);
            foreach (var item in fields)
            {
                var objs = item.GetCustomAttributes(typeof(T),false); //获取到自定的属性
    
                if (objs.Length > 0)  //排除自动属性生成的东西
                {
                    T obj = (T)objs[0]; //只定义了一个属性 => 并强制转换成了 PropertyDesc
                    Type attrType = obj.GetType();  // 继续反射
                    PropertyInfo pi = attrType.GetProperty("Desc");  //获取指定的属性
                    string value = pi.GetValue(obj,null).ToString(); //获取指定属性的值
                    dic.Add(item.Name,value); //添加到字典;
    
                }
            }
                      
        }
    
    }
    
    
    
    /// <summary>
    /// 似乎,我们的额版本二更为强大一些;
    /// </summary>
    public static class EnumExtensions
    {
        //自然就有我们的 优化版本的东西滴呀; 线程安全,并且带自定扩展方法的操作,十分完美的集合;
    
        private static ConcurrentDictionary<Type, Dictionary<object, string>> _cache = new ConcurrentDictionary<Type, Dictionary<object, string>>();
    
        public static string GetDescription(this Enum value)
        {
    
            if (value == null)
            {
                return string.Empty;
            }
            string val = value.ToString();
            //在首次载入添加页面的时候,有些数据可能未空,所以这里必要时添加判断
            if(string.IsNullOrEmpty(val) || val == "0")
            {
                return string.Empty;
            }
            string fielName = value.ToString();
            var type = value.GetType();
    
            Dictionary<object, string> nameDescriptions = null;
    
            nameDescriptions = _cache.GetOrAdd(type,(tempType) =>
            {
                Dictionary<object, string> temp = new Dictionary<object, string>();
                //获取枚举中的所有值;(字段值)
                var enmus = Enum.GetValues(tempType);
    
                foreach (var en in enmus)
                {
                    var field = tempType.GetField(Enum.GetName(tempType,en)); //指定的字段; 等同于 en.ToString()
                    //获取每一个枚举值中的description attribute
                    //获取到指定的field;
                    if (field != null)
                    {
    
                        //获取指定字段的自定义属性;
                        var des = Attribute.GetCustomAttribute(field,typeof(DescriptionAttribute)) as DescriptionAttribute;
    
                        if (des != null)
                        {
                            temp.Add(en,des.Description);
                        }
                        else
                        {
                            temp.Add(en,Convert.ToString(en));
                        }
    
                    }
                }
                return temp;
            });
    
            string description = null;  //大致的思路都是先将所有的枚举description(一次性将所有的)加入我们的 cache 中,然后再从中取出;
            nameDescriptions.TryGetValue(value,out description);
            return description;
    
        }
    }
    
    
    namespace ConsoleApplication58
    {
        class Program
        {
    
            static void Test()
            {
    
                var a=enumHelper<PropertyDesc>.GetEnumDescription(Product.computer);
                var b=enumHelper<PropertyDesc>.GetEnumDescription(Product.computer);
                var c = enumHelper<PropertyDesc>.GetEnumDescription(Product.Tv);
                var d = enumHelper<PropertyDesc>.GetEnumDescription(Product.Tv);
    
                Console.WriteLine(a);
                Console.WriteLine(b);
                Console.WriteLine(c);
                Console.WriteLine(d);
    
                Console.WriteLine("-----------------");
    
                //DescriptionAttribute 是我们组件中 一个封装好的 继承自我们的Attribute 中的一个类;
                Console.WriteLine(Product.computer.GetDescription());
    
    
    
            }
    
            static void Main(string[] args)
            {
    
                Test();
    
                Console.ReadLine();
            }
        }
    }
  • 相关阅读:
    JS实现菜单滚动到一定高度后固定
    原生js如何获取某一元素的高度
    在Vue项目中,添加的背景图片在服务器上不显示,如何处理
    单行文本截断 text-overflow
    使用line-height垂直居中在安卓手机上效果不好
    css 苹方字体
    十二. for of 示例 (可以解决大多数应用场景)
    npm详解
    webpack搭建服务器,随时修改刷新
    探讨弹性布局Flexible Box
  • 原文地址:https://www.cnblogs.com/mc67/p/7646355.html
Copyright © 2011-2022 走看看