Net特性类Description了解下
程序员文章站
2022-07-06 22:48:07
NET特性类都有个特点类名+Attribute,继承基类Attribute,我们看下微软自带的特性类:DescriptionAttribute namespace System.ComponentModel { // 摘要: // 指定属性或事件的说明。 [AttributeUsage(Attrib ......
NET特性类都有个特点类名+Attribute,继承基类Attribute,我们看下微软自带的特性类:DescriptionAttribute
namespace System.ComponentModel { // 摘要: // 指定属性或事件的说明。 [AttributeUsage(AttributeTargets.All)] public class DescriptionAttribute : Attribute { // 摘要: // 指定 System.ComponentModel.DescriptionAttribute 的默认值,即空字符串 ("")。此 static 字段是只读的。 public static readonly DescriptionAttribute Default; // 摘要: // 不带参数初始化 System.ComponentModel.DescriptionAttribute 类的新实例。 public DescriptionAttribute(); // // 摘要: // 初始化 System.ComponentModel.DescriptionAttribute 类的新实例并带有说明。 // // 参数: // description: // 说明文本。 [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public DescriptionAttribute(string description); // 摘要: // 获取存储在此特性中的说明。 // // 返回结果: // 存储在此特性中的说明。 public virtual string Description { get; } // // 摘要: // 获取或设置作为说明存储的字符串。 // // 返回结果: // 作为说明存储的字符串。默认值为空字符串 ("")。 protected string DescriptionValue { get; set; } // 摘要: // 返回给定对象的值是否等于当前的 System.ComponentModel.DescriptionAttribute。 // // 参数: // obj: // 要进行值的相等性测试的对象。 // // 返回结果: // 如果给定对象的值等于当前对象的值,则为 true;否则为 false。 public override bool Equals(object obj); public override int GetHashCode(); // // 摘要: // 返回一个值,该值指示这是否为默认 System.ComponentModel.DescriptionAttribute 实例。 // // 返回结果: // 如果这是默认 System.ComponentModel.DescriptionAttribute 实例,则为 true;否则为 false。 public override bool IsDefaultAttribute(); } }
看完这个类,我们了解到,此类是用来描述什么的,作用对象可以是类、属性、字段、接口、抽象、xxx
我们来看个作用对象为类的,我们定义一个人的类型,有两个属性 姓名和性别
public class Person { [Description("姓名")] public string Name { get; set; } [Description("性别")] public int Sex { get; set; } }
是不是觉得很熟悉,网上很多ORM工具生成的代码是不是和上面很像,但大多数都是自定义特性类
其实特性类,在我们实际做项目中起到很大的作用,本人举一个场景,在做报表的过程中,导出EXCEL过程中,列名和列的类型都是很有讲究的,一般我们准备的数据大多数都是List集合
List对象就是一个类,我们可以用到特性类来描述每列的中文名称,再读取字段类型,基本都是可以满足导出功能,下面看一个封装代码
public class ReflectionHelper<T> where T : new() { /// <summary> /// 获取特性信息 /// </summary> /// <param name="t"></param> /// <returns></returns> public static List<PropertityFieldInfo> GetPropertiyInfo() { List<PropertityFieldInfo> listRtn = new List<PropertityFieldInfo>(); Dictionary<int, string> dicPropertiy = new Dictionary<int, string>(); Dictionary<int, Type> dicFiled = new Dictionary<int, Type>(); Dictionary<int, string> dicFiledName = new Dictionary<int, string>(); T obj = new T(); var pindex = 0; var properties = obj.GetType().GetProperties(); var files = obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); foreach (var p in properties) { var v = (DescriptionAttribute[])p.GetCustomAttributes(typeof(DescriptionAttribute), false); var desc = v[0].Description; dicFiledName.Add(pindex, p.Name); dicPropertiy.Add(pindex, desc); pindex++; } var findex = 0; foreach (var f in files) { var fieldType = f.FieldType; dicFiled.Add(findex, fieldType); findex++; } foreach (KeyValuePair<int, string> kv in dicPropertiy) { PropertityFieldInfo m = new PropertityFieldInfo(); m.Name = dicFiledName[kv.Key]; m.Desc = dicPropertiy[kv.Key]; m.Type = dicFiled[kv.Key]; listRtn.Add(m); } return listRtn; } /// <summary> /// 获取所有列名描述 /// </summary> /// <returns></returns> public static List<string> GetPropertiyDescInfo() { List<string> list = new List<string>(); var propertiyInfos = GetPropertiyInfo(); foreach (var item in propertiyInfos) { list.Add(item.Desc); } return list; } } public class PropertityFieldInfo { public string Name { get; set; } public string Desc { get; set; } public Type Type { get; set; } }
控制台运行下
class Program { static void Main(string[] args) { var dic = ReflectionHelper<Person>.GetPropertiyInfo(); foreach (var kv in dic) { Console.WriteLine(kv.Name); Console.WriteLine(kv.Type); Console.WriteLine(kv.Desc); } Console.Read(); } }
看结果
ReflectionHelper,此类方法中有用到反射和泛型,关于反射和泛型大家可以自己去学习下,大家可以举一反三自己写个特性类,其实我们博客也有写
希望此文章对小伙伴们有帮助,喜欢的点个赞,谢谢!