Ejemplo n.º 1
0
        //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);
        }