.Net中提供了两种方式访问类型的元数据:System.Reflection命名空间中提供的反射API和TypeDescriptor类。
反射适用于所有类型的常规机制,它为类型返回的信息是不可扩展的,因为它不能再编译之后修改。
与此相反,TypeDescriptor是一种可扩展的组件,实现了IComponent接口。
TypeDescriptor有缓存功能,第一次反射,以后就自动缓存了。所以如果你自己懒得缓存反射结果,那么优先使用 TypeDescriptor
下面是一些TypeDescriptor的案例:
案例1:使用TypeDescriptor给类动态添加Attribute,只能通过TypeDescriptor获取Attribute(也可以给对象动态添加Attribute,使用AddAttributes的另一个重载)
TypeDescriptor.AddAttributes(typeof(targetObject), new simpleAttribute(new targetObject())); AttributeCollection collection = TypeDescriptor.GetAttributes(typeof(targetObject)); simpleAttribute attr = ((simpleAttribute)collection[typeof(simpleAttribute)]);
案例2:获取属性成员
var defaults = new { controller = "Home", action = "Index", id = UrlParameter.Optional }; PropertyDescriptorCollection props = TypeDescriptor.GetProperties(defaults); foreach (PropertyDescriptor prop in props) { object val = prop.GetValue(defaults); Console.WriteLine("name:{0}, value:{1}", prop.Name, val); }
案例3:泛型转换器
1 public static class StringExtension 2 { 3 public static T Convert<T>(this string input) 4 { 5 try 6 { 7 var converter = TypeDescriptor.GetConverter(typeof(T)); 8 if (converter != null) 9 { 10 return (T)converter.ConvertFromString(input); 11 } 12 return default(T); 13 } 14 catch (Exception) 15 { 16 return default(T); 17 } 18 } 19 20 public static object Convert(this string input, Type type) 21 { 22 try 23 { 24 var converter = TypeDescriptor.GetConverter(type); 25 if (converter != null) 26 { 27 return converter.ConvertFromString(input); 28 } 29 return null; 30 } 31 catch (Exception) 32 { 33 return null; 34 } 35 } 36 37 }
-------------------------------------------------------
"111".Convert<double>();
"True".Convert<bool>();