本节重点不讲反射机制,而是讲lambda表达式树来替代反射中常用的获取属性和方法,来达到相同的效果但却比反射高效。
每个人都知道,用反射调用一个方法或者对属性执行SetValue和GetValue操作的时候都会比直接调用慢很多,这其中设计到CLR中内部的处理,不做深究。然而,我们在某些情况下又无法不使用反射,比如:在一个ORM框架中,你要将一个DataRow转化为一个对象,但你又不清楚该对象有什么属性,这时候你就需要写一个通用的泛型方法来处理,以下代码写得有点恶心,但不妨碍理解意思:
//将DataReader转化为一个对象
private static T GetObj<T>(SqliteDataReader reader) where T : class
{
T obj = new T();
PropertyInfo[] pros = obj.GetType().GetProperties();
foreach (PropertyInfo item in pros)
{
try
{
Int32 Index = reader.GetOrdinal(item.Name);
String result = reader.GetString(Index);
if (typeof(String) == item.PropertyType)
{
item.SetValue(obj, result);
continue;
}
if (typeof(DateTime) == item.PropertyType)
{
item.SetValue(obj, Convert.ToDateTime(result));
continue;
}
if (typeof(Boolean) == item.PropertyType)
{
item.SetValue(obj, Convert.ToBoolean(result));
continue;
}
if (typeof(Int32) == item.PropertyType)
{
item.SetValue(obj, Convert.ToInt32(result));
continue;
}
if (typeof(Single) == item.PropertyType)
{
item.SetValue(obj, Convert.ToSingle(result));
continue;
}
if (typeof(Single) == item.PropertyType)
{
item.SetValue(obj, Convert.ToSingle(result));
continue;
}
if (typeof(Double) == item.PropertyType)
{
item.SetValue(obj, Convert.ToDouble(result));
continue;
}
if (typeof(Decimal) == item.PropertyType)
{
item.SetValue(obj, Convert.ToDecimal(result));
continue;
}
if (typeof(Byte) == item.PropertyType)
{
item.SetValue(obj, Convert.ToByte(result));
continue;
}
}
catch (ArgumentOutOfRangeException ex)
{
continue;
}
}
return obj;
}