//private static string GetConvertName(Type type) //{ // return ConvertMethodNames[type]; //} /// <summary>将字典类型转换成对象的委托 /// </summary> public static Func <Dictionary <string, object>, T> GetObjectFunc <T>() where T : class, new() { var sourceType = typeof(Dictionary <string, object>); var targetType = typeof(T); // define the parameter var parameterExpr = Expression.Parameter(sourceType, "x"); //collect the body var bodyExprs = new List <Expression>(); // 初始化对象 var objectExpr = Expression.Variable(targetType, "obj"); var newObjectExpr = Expression.New(targetType); var assignObjectExpr = Expression.Assign(objectExpr, newObjectExpr); bodyExprs.Add(assignObjectExpr); //获取T的全部公有属性 var properties = PropertyInfoUtil.GetProperties(targetType); foreach (var property in properties) { var nameExpr = Expression.Constant(property.Name); var fieldExpr = Expression.PropertyOrField(objectExpr, property.Name); //将object转换为对应的属性类型,int,double... // 要调用索引必须先获取PropertyType类型 PropertyInfo indexer = (from p in parameterExpr.Type.GetTypeInfo().GetDefaultMembers().OfType <PropertyInfo>() // This check is probably useless. You can't overload on return value in C#. where p.PropertyType == typeof(object) let q = p.GetIndexParameters() // Here we can search for the exact overload. Length is the number of "parameters" of the indexer, and then we can check for their type. where q.Length == 1 && q[0].ParameterType == typeof(string) select p).Single(); var indexValueExpr = Expression.Property(parameterExpr, indexer, nameExpr); //属性值 var castIndexValueExpr = Expression.Convert(indexValueExpr, property.PropertyType); //调用 Convert.ChangeType(object,xxx) //var convertMethodExpr = Expression.Call(null, /* 另外的代码, typeof(Convert).GetTypeInfo().GetMethod(GetConvertName(property.PropertyType), new Type[] { typeof(object) }), indexValueExpr);*/ var assignFieldExpr = Expression.Assign(fieldExpr, castIndexValueExpr); var notNullExpr = Expression.IfThen(Expression.NotEqual(indexValueExpr, Expression.Constant(null)), assignFieldExpr); //contains方法 var containMethodExpr = Expression.Call(parameterExpr, sourceType.GetTypeInfo().GetMethod("ContainsKey", new[] { typeof(string) }), nameExpr); var ifContainExpr = Expression.IfThen(containMethodExpr, notNullExpr); bodyExprs.Add(ifContainExpr); } //返回 bodyExprs.Add(objectExpr); var methodBodyExpr = Expression.Block(targetType, new[] { objectExpr }, bodyExprs); var lambdaExpr = Expression.Lambda <Func <Dictionary <string, object>, T> >(methodBodyExpr, parameterExpr); var func = lambdaExpr.Compile(); return(func); }