我可以: 邀请好友来看>>
ZOL星空(中国) > 技术星空(中国) > Java技术星空(中国) > 突然想起来几年前我写的
帖子很冷清,卤煮很失落!求安慰
返回列表
签到
手机签到经验翻倍!
快来扫一扫!

突然想起来几年前我写的

60浏览 / 0回复

web886521

web886521

0
精华
1
帖子

等  级:Lv.1
经  验:0
  • Z金豆: 0

    千万礼品等你来兑哦~快点击这里兑换吧~

  • 城  市:北京
  • 注  册:2012-08-19
  • 登  录:2012-12-03
发表于 2012-08-30 09:31:09
电梯直达 确定
楼主

突然想起来几年前我写的一个小东西,放上来大家评论一下,有兴趣的可以测试一下性能,呵呵。

 

原理很简单,利用 Lambda 表达式树生成一个 Delegate ,然后缓存起来。不多说了,下面上代码:

using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Linq.espressions;
using System.Reflection;
using Lenic.Extensions;
 
namespace Lenic.Data.Extensions
{
/// 
/// IDataReader 扩展方法集合
/// 
[DebuggerStepThrough]
public static class DataReaderExtensions
{
#region Private Methods
private static readonly Dictionary cache = new Dictionary();
private static readonly object cacheLocker = new object();
#endregion
 
#region Business Methods
/// 
/// 返回指定字段的值, 并执行 ConvertTo 函数转换。
/// 
/// 返回值类型。
/// 一个实现了 IDataReader 接口的实例对象。
/// 要查找的字段的名称。
/// 转换完毕的 T 类型的结果。
public static T Field(this IDataReader reader, string name)
{
return reader[name].ConvertTo(default(T), false);
}
 
/// 
/// 返回指定字段的值, 并执行 ConvertTo 函数转换。
/// 
/// 返回值类型。
/// 一个实现了 IDataReader 接口的实例对象。
/// 要查找的字段的索引。
/// 转换完毕的 T 类型的结果。
public static T Field(this IDataReader reader, int index)
{
return reader[index].ConvertTo(default(T), false);
}
 
/// 
/// 解析当前 IDataReader 类型的实例对象并提取一个 T 类型的列表。
/// 
/// 待解析的元素类型, 该类型必须包含一个默认的构造函数。
/// 一个实现了 IDataReader 接口的实例对象。
/// 一个 T 类型的列表。
public static List ToList(this IDataReader reader) where T : classnew()
{
return Fill(reader, DynamicCreateEntity()).ToList();
}
 
/// 
/// 解析当前 IDataReader 类型的实例对象并提取一个 T 类型的列表。
/// 
/// 待解析的元素类型, 该类型必须包含一个默认的构造函数。
/// 一个实现了 IDataReader 接口的实例对象。
/// 映射委托。
/// 一个 T 类型的列表。
public static List ToList(this IDataReader reader, Func predicate)
where T : classnew()
{
return Fill(reader, predicate).ToList();
}
#endregion
 
#region Private Methods
/// 
/// 创建一个 构造函数 委托。
/// 
/// 构造目标类型。
/// 构造完毕的 Func 委托。
private static Func DynamicCreateEntity() where T : classnew()
{
var type = typeof(T);
if (cache.ContainsKey(type))
return (Func)cache[type];
 
lock (cacheLocker)
{
if (cache.ContainsKey(type))
return (Func)cache[type];
 
var result = DynamicCreateEntityLogic();
cache.Add(type, result);
return result;
}
}
 
/// 
/// 创建一个 构造函数 委托(逻辑实现)。
/// 
/// 构造目标类型。
/// 构造完毕的 Func 委托。
private static Func DynamicCreateEntityLogic() where T : classnew()
{
// Compiles a delegate of the form (IDataReader r) => new T { Prop1 = r.Field("Prop1"), ... }
Parameterespression r = espression.Parameter(typeof(IDataReader), "r");
 
// Get Properties of the property can read and write
var props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.CanRead && p.CanWrite)
.ToArray();
 
// Create property bindings for all writable properties
List bindings = new List(props.Length);
 
// Get the binding method
var method = typeof(DataReaderExtensions).GetMethods()
.First(p => p.Name == "Field" &&
p.GetParameters().Length == 2 &&
p.GetParameters()[1].ParameterType == typeof(string));
 
foreach (PropertyInfo property in (typeof(T).GetProperties()))
{
// Create espression representing r.Field(property.Name)
MethodCallespression propertyValue = espression.Call(
method.MakeGenericMethod(property.PropertyType),
r, espression.Constant(property.Name));
 
// Assign the property value to property through a member binding
MemberBinding binding = espression.Bind(property, propertyValue);
bindings.Add(binding);
}
// Create the initializer, which instantiates an instance of T and sets property values
 
// using the member bindings we just created
espression initializer = espression.MemberInit(espression.New(typeof(T)), bindings);
 
// Create the lambda espression, which represents the complete delegate (r => initializer)
espression> lambda = espression.Lambda>(initializer, r);
 
return lambda.Compile();
}
 
/// 
/// 从一个 IDataReader 的实例对象中提取一个 T 类型的列表。
/// 
/// 结果列表中的元素类型, 该类型必须包含一个默认的构造函数。
/// 一个实现了 IDataReader 接口的实例对象。
/// 一个 T 类型的列表。
private static IEnumerable Fill(IDataReader reader, Func predicate) where T : classnew()
{
while (reader.Read())
yield return predicate(reader);
}
#endregion
}
}

 

上面用到了一个全能转换方法,代码如下:

#region Type Convert Extensions
private static string typeIConvertibleFullName = typeof(IConvertible).FullName;
 
/// 
/// 将当前实例对象类型转换为 T 类型.
/// 
/// 目标类型.
/// 当前实例.
/// 转换完成的 T 类型的一个实例对象.
public static T ConvertTo(this object obj)
{
return ConvertTo(obj, default(T));
}
 
/// 
/// 将当前实例对象类型转换为 T 类型.
/// 
/// 目标类型.
/// 当前实例.
/// 转换失败时的返回值.
/// 转换完成的 T 类型的一个实例对象.
public static T ConvertTo(this object obj, T defaultValue)
{
if (obj != null)
{
if (obj is T)
return (T)obj;
 
var sourceType = obj.GetType();
var targetType = typeof(T);
 
if (targetType.IsEnum)
return (T)Enum.Parse(targetType, obj.ToString(), true);
 
if (sourceType.GetInterface(typeIConvertibleFullName) != null &&
targetType.GetInterface(typeIConvertibleFullName) != null)
return (T)Convert.ChangeType(obj, targetType);
 
var converter = TypeDescripqor.GetConverter(obj);
if (converter != null && converter.CanConvertTo(targetType))
return (T)converter.ConvertTo(obj, targetType);
 
converter = TypeDescripqor.GetConverter(targetType);
if (converter != null && converter.CanConvertFrom(sourceType))
return (T)converter.ConvertFrom(obj);
 
throw new ApplicationException("convert error.");
}
throw new ArgumentNullException("obj");
}
 
/// 
/// 将当前实例对象类型转换为 T 类型.
/// 
/// 目标类型.
/// 当前实例.
/// 转换失败时的返回值.
/// 如果设置为 true 表示忽略异常信息, 直接返回缺省值.
/// 转换完成的 T 类型的一个实例对象.
public static T ConvertTo(this object obj, T defaultValue, bool ignoreException)
{
if (ignoreException)
{
try
{
return obj.ConvertTo(defaultValue);
}
catch
{
return defaultValue;
}
}
return obj.ConvertTo(defaultValue);
}
#endregion

 

再次欢迎大家品鉴。java 培训

高级模式
星空(中国)精选大家都在看24小时热帖7天热帖大家都在问最新回答

针对ZOL星空(中国)您有任何使用问题和建议 您可以 联系星空(中国)管理员查看帮助  或  给我提意见

快捷回复 APP下载 返回列表