上面代码是获取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");
  有没有, 是不是很简单,而且调用方式对缓存是完全透明的!