Ejemplo n.º 1
0
        /// <summary>
        /// 将对象转换成字典类型委托
        /// </summary>
        public static Func <T, Dictionary <string, object> > GetDictionaryFunc <T>() where T : class, new()
        {
            var sourceType = typeof(T);
            var targetType = typeof(Dictionary <string, object>);
            // define the parameter
            var parameterExpr = Expression.Parameter(sourceType, "x");
            //collect the body
            var bodyExprs = new List <Expression>();

            var dictExpr       = Expression.Variable(targetType, "dict");
            var newDictExpr    = Expression.New(targetType);
            var assignDictExpr = Expression.Assign(dictExpr, newDictExpr);

            bodyExprs.Add(assignDictExpr);
            var properties = PropertyInfoUtil.GetProperties(sourceType);

            foreach (var property in properties)
            {
                var nameExpr      = Expression.Constant(property.Name);
                var castValueExpr = Expression.Convert(Expression.Property(parameterExpr, property), typeof(object));

                var addMethodExpr = Expression.Call(dictExpr,
                                                    targetType.GetTypeInfo().GetMethod("Add", new[] { typeof(string), typeof(object) }), nameExpr,
                                                    castValueExpr);
                //添加Null
                var addNullMethodExpr = Expression.Call(dictExpr, targetType.GetTypeInfo().GetMethod("Add", new[] { typeof(string), typeof(object) }), nameExpr, Expression.Constant(null));


                var ifNotNullElseExpr = Expression.IfThenElse(Expression.NotEqual(castValueExpr, Expression.Constant(null)),
                                                              addMethodExpr, addNullMethodExpr);
                bodyExprs.Add(ifNotNullElseExpr);
            }
            //返回
            bodyExprs.Add(dictExpr);
            var methodBodyExpr = Expression.Block(targetType, new[] { dictExpr }, bodyExprs);

            var lambdaExpr = Expression.Lambda <Func <T, Dictionary <string, object> > >(methodBodyExpr, parameterExpr);
            var func       = lambdaExpr.Compile();

            return(func);
        }
Ejemplo n.º 2
0
        //private static readonly IDictionary<Type, string> ConvertMethodNames = new ConcurrentDictionary<Type, string>()
        //{
        //    [typeof(short)] = "ToInt16",
        //    [typeof(int)] = "ToInt32",
        //    [typeof(long)] = "ToInt64",
        //    [typeof(double)] = "ToDouble",
        //    [typeof(decimal)] = "ToDecimal",
        //    [typeof(string)] = "ToString",
        //    [typeof(DateTime)] = "ToDateTime",
        //    [typeof(byte)] = "ToByte",
        //    [typeof(char)] = "ToChar",
        //    [typeof(bool)] = "ToBoolean",

        //    [typeof(short?)] = "ToInt16",
        //    [typeof(int?)] = "ToInt32",
        //    [typeof(long?)] = "ToInt64",
        //    [typeof(double?)] = "ToDouble",
        //    [typeof(decimal?)] = "ToDecimal",
        //    [typeof(DateTime?)] = "ToDateTime",
        //    [typeof(byte?)] = "ToByte",
        //    [typeof(char?)] = "ToChar",
        //    [typeof(bool?)] = "ToBoolean"
        //};

        /// <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);
        }
Ejemplo n.º 3
0
        /// <summary>获取字典转换成对象的委托
        /// </summary>
        public static Func <Dictionary <string, string>, T> GetObjectFunc <T>() where T : class, new()
        {
            if (typeof(ICollection).GetTypeInfo().IsAssignableFrom(typeof(T)))
            {
                throw new NotSupportedException("Not support type: ICollection");
            }
            var           type          = typeof(T);
            var           properties    = PropertyInfoUtil.GetProperties(type);
            DynamicMethod dynamicMethod = new DynamicMethod("DictionaryToObject", type,
                                                            new Type[] { typeof(Dictionary <string, string>) }, type, true)
            {
                InitLocals = false
            };
            ILGenerator il = dynamicMethod.GetILGenerator();
            //结束标签
            Label endLabel = il.DefineLabel();
            //定义变量 var user=new User();他为第0个变量
            LocalBuilder obj   = il.DeclareLocal(type);
            LocalBuilder value = il.DeclareLocal(typeof(string));

            // ReSharper disable once AssignNullToNotNullAttribute
            il.Emit(OpCodes.Newobj, type.GetTypeInfo().GetConstructor(Type.EmptyTypes));
            il.Emit(OpCodes.Stloc, obj);
            foreach (var property in properties)
            {
                Label endIfLabel = il.DefineLabel();
                //判断是否包含key
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldstr, property.Name);
                il.Emit(OpCodes.Callvirt, DictionaryContainsKey);
                var tmp0 = il.DeclareLocal(typeof(int));
                il.Emit(OpCodes.Stloc, tmp0);
                il.Emit(OpCodes.Ldloc, tmp0);
                il.Emit(OpCodes.Brfalse_S, endIfLabel);

                //是否为空判断
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldstr, property.Name);
                il.Emit(OpCodes.Callvirt, DictionaryGetItem);
                il.Emit(OpCodes.Stloc, value);
                il.Emit(OpCodes.Ldloc, value);
                il.Emit(OpCodes.Call, StringNull);
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                var tmp = il.DeclareLocal(typeof(int));
                il.Emit(OpCodes.Stloc, tmp);
                il.Emit(OpCodes.Ldloc, tmp);
                il.Emit(OpCodes.Brfalse_S, endIfLabel);

                il.Emit(OpCodes.Ldloc, obj);
                il.Emit(OpCodes.Ldloc, value);
                Parse(il, property.PropertyType);
                il.Emit(OpCodes.Callvirt, property.GetSetMethod());

                il.MarkLabel(endIfLabel);
            }
            var result = il.DeclareLocal(type);

            il.Emit(OpCodes.Ldloc, obj);
            il.Emit(OpCodes.Stloc_S, result);
            il.Emit(OpCodes.Br_S, endLabel);
            il.MarkLabel(endLabel);
            il.Emit(OpCodes.Ldloc_S, result);
            il.Emit(OpCodes.Ret);

            var func =
                dynamicMethod.CreateDelegate(typeof(Func <Dictionary <string, string>, T>)) as Func <Dictionary <string, string>, T>;

            if (func == null)
            {
                throw new VerificationException();
            }
            return(func);
        }
Ejemplo n.º 4
0
        /// <summary>获取将对象转换成字典类型的委托
        /// </summary>
        public static Func <T, Dictionary <string, string> > GetDictionaryFunc <T>()
        {
            if (typeof(ICollection).GetTypeInfo().IsAssignableFrom(typeof(T)))
            {
                throw new NotSupportedException("Not support type: ICollection");
            }
            var           type          = typeof(Dictionary <string, string>);
            var           properties    = PropertyInfoUtil.GetProperties(typeof(T));
            DynamicMethod dynamicMethod = new DynamicMethod("ObjectToDictionary", type,
                                                            new Type[] { typeof(T) }, typeof(object), true)
            {
                InitLocals = true
            };
            ILGenerator il = dynamicMethod.GetILGenerator();
            //结束标签
            Label endLabel = il.DefineLabel();
            //定义变量 var user=new User();他为第0个变量
            LocalBuilder obj = il.DeclareLocal(type);
            //定义了可空类型的变量集合
            Dictionary <Type, LocalBuilder> valueDict = new Dictionary <Type, LocalBuilder>();

            // ReSharper disable once AssignNullToNotNullAttribute
            il.Emit(OpCodes.Newobj, type.GetTypeInfo().GetConstructor(Type.EmptyTypes));
            il.Emit(OpCodes.Stloc, obj);
            int index = 0;

            foreach (var property in properties)
            {
                Label endIfLabel = il.DefineLabel();

                //string,可空类型需要null判断
                if (property.PropertyType == typeof(string))
                {
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Callvirt, property.GetGetMethod());
                    il.Emit(OpCodes.Ldnull);
                    il.Emit(OpCodes.Cgt_Un);
                    var tmp = il.DeclareLocal(typeof(bool));
                    il.Emit(OpCodes.Stloc, tmp);
                    il.Emit(OpCodes.Ldloc, tmp);
                    il.Emit(OpCodes.Brfalse_S, endIfLabel);
                }
                //可空类型
                if (EmitUtil.IsNullable(property.PropertyType))
                {
                    var hasValue = il.DeclareLocal(typeof(bool));
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Callvirt, property.GetGetMethod());
                    var local = GetLocal(il, property.PropertyType, valueDict);
                    il.Emit(OpCodes.Stloc_S, local);
                    il.Emit(OpCodes.Ldloca_S, local);
                    il.Emit(OpCodes.Call, property.PropertyType.GetTypeInfo().GetMethod("get_HasValue", new Type[] { }));
                    if (index == 0)
                    {
                        il.Emit(OpCodes.Stloc, hasValue);
                        il.Emit(OpCodes.Ldloc, hasValue);
                    }
                    else
                    {
                        il.Emit(OpCodes.Stloc_S, hasValue);
                        il.Emit(OpCodes.Ldloc_S, hasValue);
                    }
                    index++;
                    il.Emit(OpCodes.Brfalse_S, endIfLabel);
                }

                il.Emit(OpCodes.Ldloc, obj);
                il.Emit(OpCodes.Ldstr, property.Name);
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Callvirt, property.GetGetMethod()); //取对象属性值
                PropertyToString(il, property.PropertyType, valueDict);
                il.Emit(OpCodes.Callvirt, DictionaryAddItem);
                il.MarkLabel(endIfLabel);
            }
            var result = il.DeclareLocal(type);

            il.Emit(OpCodes.Ldloc, obj);
            il.Emit(OpCodes.Stloc_S, result);
            il.Emit(OpCodes.Br_S, endLabel);
            il.MarkLabel(endLabel);
            il.Emit(OpCodes.Ldloc_S, result);
            il.Emit(OpCodes.Ret);

            var func =
                dynamicMethod.CreateDelegate(typeof(Func <T, Dictionary <string, string> >)) as Func <T, Dictionary <string, string> >;

            if (func == null)
            {
                throw new VerificationException();
            }
            return(func);
        }