BLReflection 是我自己写的一个关于反射操作的类,在我之前关于linq的文章有用到, 希望有需要的朋友可以看看。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace Common
{
public class BLReflection
{
public static System.Data.DataTable Convert(Type t)
{
System.Data.DataTable dt = new System.Data.DataTable();
var ps = GetProperties(t);
foreach (PropertyInfo p in ps)
dt.Columns.Add(p.Name, p.PropertyType);
return dt;
}
public static List<PropertyInfo> GetProperties(Type t)
{
PropertyInfo[] ps = t.GetProperties();
return ps.ToList();
}
public static IEnumerable<object> GetPropValues(object obj)
{
Type t = obj.GetType();
var ps = GetProperties(t);
var result = from p in ps select p.GetValue(obj, null);
return result;
}
//Add in Feb 07, 2009
public static object GetPropValue(object obj, string propName)
{
Type t = obj.GetType();
var p = t.GetProperty(propName);
var result = p.GetValue(obj, null);
return result;
}
public static object[] GetPropAttributes(object obj, string propName)
{
Type t = obj.GetType();
var p = t.GetProperty(propName);
var attr = p.GetCustomAttributes(true);
return attr;
}
public static T[] GetPropAttribute<T>(object obj, string propName)
{
Type t = obj.GetType();
var p = t.GetProperty(propName);
Type attrType = typeof(T);
var attr = p.GetCustomAttributes(attrType, true) as T[];
return attr;
}
public static string[] GetPropFrom<T>(object obj, Func <T,bool > filter) where T : Attribute
{
Type t = obj.GetType();
var ps = GetProperties(t);
Type attrType = typeof(T);
List<string> result = new List<string>();
foreach (var p in ps)
{
var attr = p.GetCustomAttributes(attrType, true) as T[];
if(attr ==null) return null;
var filterResult= attr.Where(filter);
if (filterResult.Count() != 0)
{
result.Add(p.Name);
}
}
return result .ToArray();
}
public static IDictionary<string, object> ToDictionary<T>(T t) //where T : class
{
Type type = t.GetType();
PropertyInfo[] ps = type.GetProperties();
IDictionary<string, object> result = new Dictionary<string, object>(ps.Length);
foreach (var p in ps)
result.Add(p.Name, p.GetValue(t, null));
return result;
}
public static string GetClassName<T>() where T : class
{
var className = typeof(T).Name;
return className;
}
public static T Parse<T>(string str) where T : struct
{
var type = typeof(T);
var result = Parse(type, str);
return (T)result;
}
public static object Parse(Type type, string str)
{
// var m = type.GetMethod("Parse", new Type[] { typeof(String) });
var m = MFactory.GetParseMethod(type);
if (m == null) return str;
object result = m.Invoke(null, new object[] { str });
return result;
}
}
public static class MFactory
{
private static Dictionary<Type, MethodInfo> _methods = null;
public static Dictionary<Type, MethodInfo> Methods
{
get
{
if (_methods == null)
_methods = new Dictionary<Type, MethodInfo>();
return _methods;
}
}
public static MethodInfo GetParseMethod(Type type)
{
if (!Methods.ContainsKey(type))
{
MethodInfo m = type.GetMethod("Parse", new Type[] { typeof(String) });
Methods.Add(type, m);
}
return Methods[type];
}
}
}
这里主要说说Parse的用法, 因为其他方法对于会Reflection的人来说已经是很简单的事情了。 BLRelection.Parse 是动态调用基本数据类型的Parse方法(当然其他有Parse公共方法的类也可以)。而MFactory类是对这些Parse方法做一个缓存,以后调用同一类型的Parse方法就会快多了(毕竟反射是比较慢的,相信用过的人都知道)。
一个小例子: int data = BLReflection.Parse(typeof(int), "121212"); //结果是data=121212
这个例子不足于说明这个方法的通用性。但是我没有时间写一个更好的例子来说明,在这里就简单说说关于数据转换的一个实例吧—— 譬如有一个form, 里面有一些基本的录入(例如说录入User, User 类是这个样子{Name, Age, Height}, 那么这个form就有3个textbox, 分别是txtName,txtAge, txtHeight),通常我们的做法是:
User user= new User();
user.Name= txtName.Text ;
user.Age = int.Parse(txtAge.Text);
user.Height = double.Parse(txtHeight.Text); //假如Height是175.5 这样类型数据的话
我们也可以借用反射来写个公共的方法处理:
public void UpdateModel<T> (T t, Control[] controls)
{
//1. 反射T, 得到所有属性
//2. 根据属性名来匹配控件名
//3. 如果找到匹配的控件名, 根据这个属性类型来动态把控件的内容写入实现:xx.SetValue(obj, BLRlection.Parse(xx.PropertyType, controls[i]));
// .....
}
有点IOC的味道, 呵呵(暗喜。。。)。
但在实际应用中不会用到(原因:1.效率, 2.数据类型一般不会这么简单)(回到现实 - . -!)