C# 中自定义Attribute值的获取与优化
来源:互联网 发布:ios 单向链式编程 编辑:程序博客网 时间:2024/06/06 09:22
C#自定义Attribute值的获取是开发中会经常用到的,一般我们的做法也就是用反射进行获取的,代码也不是很复杂。
1、首先有如下自定义的Attribute
[AttributeUsage(AttributeTargets.All)] public sealed class NameAttribute : Attribute { private readonly string _name; public string Name { get { return _name; } } public NameAttribute(string name) { _name = name; } }2、定义一个使用NameAttribute的类
[Name("dept")] public class CustomAttributes { [Name("Deptment Name")] public string Name { get; set; } [Name("Deptment Address")] public string Address; }
3、获取CustomAttributes类上的"dept"也就很简单了
private static string GetName() { var type = typeof(CustomAttributes); var attribute = type.GetCustomAttributes(typeof(NameAttribute), false).FirstOrDefault(); if (attribute == null) { return null; } return ((NameAttribute)attribute).Name; }以上代码就可以简单的获取,类上的Attribute的值了,但是需求往往不是这么简单的,不仅要获取类头部Attribute上的值,还要获取字段Address头部Attribute上的值。有的同学可能就觉得这还不简单呀,直接上代码
private static string GetAddress() { var type = typeof (CustomAttributes); var fieldInfo = type.GetField("Address"); if (fieldInfo == null) { return null; } var attribute = fieldInfo.GetCustomAttributes(typeof(NameAttribute), false).FirstOrDefault(); if (attribute == null) { return null; } return ((NameAttribute) attribute).Name; }上面代码就是获取Address字段头部上的Attribute值了。虽然我们是获取到了我们想要的,但是我们发现这样做是不是太累了,如果又扩展一个自定义的Attribute,或者又在一个新的属性或字段上标上Attribute时,我们又要写一段代码来实现我想要的,这些严重代码违反了DRY的设计原则。我们知道获取Attribute是通过反射来取的,Attribute那个值又是不变的,这样就没必要每次都要进行反射来获取了。基于以上两点代码进行了如下的优化,优化后的代码如下:
public static class CustomAttributeHelper { /// <summary> /// Cache Data /// </summary> private static readonly Dictionary<string, string> Cache = new Dictionary<string, string>(); /// <summary> /// 获取CustomAttribute Value /// </summary> /// <typeparam name="T">Attribute的子类型</typeparam> /// <param name="sourceType">头部标有CustomAttribute类的类型</param> /// <param name="attributeValueAction">取Attribute具体哪个属性值的匿名函数</param> /// <returns>返回Attribute的值,没有则返回null</returns> public static string GetCustomAttributeValue<T>(this Type sourceType, Func<T, string> attributeValueAction) where T : Attribute { return GetAttributeValue(sourceType, attributeValueAction, null); } /// <summary> /// 获取CustomAttribute Value /// </summary> /// <typeparam name="T">Attribute的子类型</typeparam> /// <param name="sourceType">头部标有CustomAttribute类的类型</param> /// <param name="attributeValueAction">取Attribute具体哪个属性值的匿名函数</param> /// <param name="name">field name或property name</param> /// <returns>返回Attribute的值,没有则返回null</returns> public static string GetCustomAttributeValue<T>(this Type sourceType, Func<T, string> attributeValueAction, string name) where T : Attribute { return GetAttributeValue(sourceType, attributeValueAction, name); } private static string GetAttributeValue<T>(Type sourceType, Func<T, string> attributeValueAction, string name) where T : Attribute { var key = BuildKey(sourceType, name); if (!Cache.ContainsKey(key)) { CacheAttributeValue(sourceType, attributeValueAction, name); } return Cache[key]; } /// <summary> /// 缓存Attribute Value /// </summary> private static void CacheAttributeValue<T>(Type type, Func<T, string> attributeValueAction, string name) { var key = BuildKey(type, name); var value = GetValue(type, attributeValueAction, name); lock (key + "_attributeValueLockKey") { if (!Cache.ContainsKey(key)) { Cache[key] = value; } } } private static string GetValue<T>(Type type, Func<T, string> attributeValueAction, string name) { object attribute = null; if (string.IsNullOrEmpty(name)) { attribute = type.GetCustomAttributes(typeof (T), false).FirstOrDefault(); } else { var propertyInfo = type.GetProperty(name); if (propertyInfo != null) { attribute = propertyInfo.GetCustomAttributes(typeof (T), false).FirstOrDefault(); } var fieldInfo = type.GetField(name); if (fieldInfo != null) { attribute = fieldInfo.GetCustomAttributes(typeof (T), false).FirstOrDefault(); } } return attribute == null ? null : attributeValueAction((T) attribute); } /// <summary> /// 缓存Collection Name Key /// </summary> private static string BuildKey(Type type, string name) { if (string.IsNullOrEmpty(name)) { return type.FullName; } return type.FullName + "." + name; } }
以上优化后的代码:
把不同的代码用泛型T,Fun<T,stirng>来处理来减少重复的代码;
把取过的Attribute值存到一个Dictionary中,下次再来取时,如果有则直接返回Dictionary中的值,如果没有才通过反射来取相应的Attribute值,这样大大的提高效率;
调用方法也更加的简单了,代码如下:
var cName=typeof(CustomAttributes).GetCustomAttributeValue<NameAttribute>(x => x.Name);var fName = typeof (CustomAttributes).GetCustomAttributeValue<NameAttribute>(x => x.Name, "Address");有没有, 是不是很简单,而且调用方式对缓存是完全透明的!
0 0
- C# 中自定义Attribute值的获取与优化
- .net c#获取自定义Attribute
- C#中Attribute的应用
- C#中Attribute的应用
- C# 使用自定义的特性Attribute
- C#自定义Attribute举例!
- C#自定义Attribute
- 【TIP_3】在代码中获取attribute值的方法
- C# Attribute的概念与使用浅析
- Firefox中获取Attribute的问题
- C# 反射获取 Metadata类,获取类的Attribute 属性
- C#中Attribute和Property的区别
- C#中attribute和property的区别
- C#中关于Attribute的基本用法
- .NET(C#):获取方法返回值的自定义特性(Attribute)
- C# 的Attribute特性 与C#的宏定义
- 自定义Attribute的使用
- DOM中Property与Attribute的区别
- VBScript把json字符串解析成json对象的2个方法
- shell小记:eval
- 在线学习网站
- Java isAssignableFrom 理解
- 最好的Python机器学习库
- C# 中自定义Attribute值的获取与优化
- java中常见的异常及处理方法
- JSeparator类 JPopupMenu类
- 意图 intent
- Android 播放mp3
- ubuntu15.10避免图形界面无法登录的jdk配置
- 第一章 Web MVC简介 —— SpringMVC
- JVM系列一:JVM内存组成及分配
- android app to app