C#自定义Attribute值的获取与优化
作者:网络转载 发布时间:[ 2015/11/11 13:15:08 ] 推荐标签:.NET 测试开发技术
上面代码是获取Address字段头部上的Attribute值了。虽然我们是获取到了我们想要的,但是我们发现这样做是不是太累了,如果又扩展一个自定义的Attribute,或者又在一个新的属性或字段上标上Attribute时,我们又要写一段代码来实现我想要的,这些严重代码违反了DRY的设计原则。我们知道获取Attribute是通过反射来取的,Attribute那个值又是不变的,这样没必要每次都要进行反射来获取了。基于以上两点代码进行了如下的优化,优化后的代码如下:
1 public static class CustomAttributeHelper
2 {
3 /// <summary>
4 /// Cache Data
5 /// </summary>
6 private static readonly Dictionary<string, string> Cache = new Dictionary<string, string>();
7
8 /// <summary>
9 /// 获取CustomAttribute Value
10 /// </summary>
11 /// <typeparam name="T">Attribute的子类型</typeparam>
12 /// <param name="sourceType">头部标有CustomAttribute类的类型</param>
13 /// <param name="attributeValueAction">取Attribute具体哪个属性值的匿名函数</param>
14 /// <returns>返回Attribute的值,没有则返回null</returns>
15 public static string GetCustomAttributeValue<T>(this Type sourceType, Func<T, string> attributeValueAction) where T : Attribute
16 {
17 return GetAttributeValue(sourceType, attributeValueAction, null);
18 }
19
20 /// <summary>
21 /// 获取CustomAttribute Value
22 /// </summary>
23 /// <typeparam name="T">Attribute的子类型</typeparam>
24 /// <param name="sourceType">头部标有CustomAttribute类的类型</param>
25 /// <param name="attributeValueAction">取Attribute具体哪个属性值的匿名函数</param>
26 /// <param name="name">field name或property name</param>
27 /// <returns>返回Attribute的值,没有则返回null</returns>
28 public static string GetCustomAttributeValue<T>(this Type sourceType, Func<T, string> attributeValueAction,
29 string name) where T : Attribute
30 {
31 return GetAttributeValue(sourceType, attributeValueAction, name);
32 }
33
34 private static string GetAttributeValue<T>(Type sourceType, Func<T, string> attributeValueAction,
35 string name) where T : Attribute
36 {
37 var key = BuildKey(sourceType, name);
38 if (!Cache.ContainsKey(key))
39 {
40 CacheAttributeValue(sourceType, attributeValueAction, name);
41 }
42
43 return Cache[key];
44 }
45
46 /// <summary>
47 /// 缓存Attribute Value
48 /// </summary>
49 private static void CacheAttributeValue<T>(Type type,
50 Func<T, string> attributeValueAction, string name)
51 {
52 var key = BuildKey(type, name);
53
54 var value = GetValue(type, attributeValueAction, name);
55
56 lock (key + "_attributeValueLockKey")
57 {
58 if (!Cache.ContainsKey(key))
59 {
60 Cache[key] = value;
61 }
62 }
63 }
64
65 private static string GetValue<T>(Type type,
66 Func<T, string> attributeValueAction, string name)
67 {
68 object attribute = null;
69 if (string.IsNullOrEmpty(name))
70 {
71 attribute =
72 type.GetCustomAttributes(typeof (T), false).FirstOrDefault();
73 }
74 else
75 {
76 var propertyInfo = type.GetProperty(name);
77 if (propertyInfo != null)
78 {
79 attribute =
80 propertyInfo.GetCustomAttributes(typeof (T), false).FirstOrDefault();
81 }
82
83 var fieldInfo = type.GetField(name);
84 if (fieldInfo != null)
85 {
86 attribute = fieldInfo.GetCustomAttributes(typeof (T), false).FirstOrDefault();
87 }
88 }
89
90 return attribute == null ? null : attributeValueAction((T) attribute);
91 }
92
93 /// <summary>
94 /// 缓存Collection Name Key
95 /// </summary>
96 private static string BuildKey(Type type, string name)
97 {
98 if (string.IsNullOrEmpty(name))
99 {
100 return type.FullName;
101 }
102
103 return type.FullName + "." + name;
104 }
105 }
以上优化后的代码:
把不同的代码用泛型T,Fun<T,stirng>来处理来减少重复的代码;
把取过的Attribute值存到一个Dictionary中,下次再来取时,如果有则直接返回Dictionary中的值,如果没有才通过反射来取相应的Attribute值,这样大大的提高效率;
调用方法也更加的简单了,代码如下:
1 var cName=typeof(CustomAttributes).GetCustomAttributeValue<NameAttribute>(x => x.Name);
2 var fName = typeof (CustomAttributes).GetCustomAttributeValue<NameAttribute>(x => x.Name, "Address");
有没有, 是不是很简单,而且调用方式对缓存是完全透明的!
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11热门文章
常见的移动App Bug??崩溃的测试用例设计如何用Jmeter做压力测试QC使用说明APP压力测试入门教程移动app测试中的主要问题jenkins+testng+ant+webdriver持续集成测试使用JMeter进行HTTP负载测试Selenium 2.0 WebDriver 使用指南