【ASP.NET编程知识】.NET获取枚举DescriptionAttribute描述信息性能改进的多种方法.docx

.NET获取枚举DescriptionAttribute描述信息性能改进的多种方法在ASP.NET编程中,获取枚举DescriptionAttribute描述信息是一个常见的需求。DescriptionAttribute特性可以用于many places,例如枚举,通过获取枚举上定义的描述信息在UI上显示。本文将讨论获取枚举描述信息的多种方法,并对每种方法进行性能分析。 1.使用反射获取DescriptionAttribute我们使用反射来获取DescriptionAttribute。这是最常见的方法,通过反射获取枚举的字段信息,然后获取DescriptionAttribute特性。 ```csharp public static string GetDescriptionOriginal(this Enum @this) { var name = @this.ToString(); var field = @this.GetType().GetField(name); if (field == null) return name; var att = System.Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute), false); return att == null ? field.Name : ((DescriptionAttribute)att).Description; } ```这种方法存在一些问题: *反射造成的性能问题,每次调用都会使用反射,效率慢! *反射会生成新的DescriptionAttribute对象,哪怕是同一个枚举值,造成内存、GC的极大浪费! 2.使用缓存机制优化性能为了解决反射造成的性能问题,我们可以使用缓存机制来优化性能。我们可以使用Dictionary来缓存枚举值和描述信息的映射关系。 ```csharp private static readonly Dictionary _cache = new Dictionary(); public static string GetDescriptionCached(this Enum @this) { var type = @this.GetType(); if (!_cache.TryGetValue(type, out var dict)) { dict = new Dictionary(); _cache[type] = dict; foreach (var field in type.GetFields()) { var att = System.Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute), false); if (att != null) { dict.Add((int)Enum.Parse(type, field.Name), ((DescriptionAttribute)att).Description); } } } return dict[@this.GetHashCode()]; } ```这种方法可以提高性能,因为我们只需要在第一次调用时使用反射获取描述信息,然后缓存起来,以后可以直接从缓存中获取。 3.使用Expression Tree优化性能我们可以使用Expression Tree来优化性能。我们可以使用Expression Tree来生成一个lambda表达式,然后使用编译后的lambda表达式来获取描述信息。 ```csharp public static string GetDescription[removed]this Enum @this) { var type = @this.GetType(); var fieldName = @this.ToString(); var field = type.GetField(fieldName); var att = System.Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute), false); var lambda = BuildLambda[removed]type, fieldName); return lambda.Compile()(@this); } private static Func BuildLambda[removed]Type type, string fieldName) { var param = Expression.Parameter(type, "e"); var field = type.GetField(fieldName); var att = System.Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute), false); var description = att != null ? ((DescriptionAttribute)att).Description : fieldName; var body = Expression.Convert(Expression.Call(typeof(DescriptionAttribute).GetMethod("ToString"), Expression.Constant(description)), typeof(string)); return Expression.Lambda(body, param).Compile(); } ```这种方法可以提高性能,因为我们可以使用编译后的lambda表达式来获取描述信息,而不需要使用反射。性能测试结果: |方法|执行时间(毫秒) |内存使用(KB) | GC次数| | --- | | GetDescriptionOriginal | 79881 | -1652.7970 | 7990 | | GetDescriptionCached | 10 | -0.0010 | | GetDescriptionExpression | 5 | -0.0010 | 0 |可以看到,使用缓存机制和Expression Tree可以大幅提高性能。
docx 文件大小:20.25KB