Ejemplo n.º 1
0
        public static Action <T, V> GetExpressionSet(string name, List <MemberParseInfo> list)
        {
            var last               = list.Last();
            var first              = list.First();
            var target             = Expression.Parameter(typeof(T), "target");
            var value              = Expression.Parameter(typeof(V), "value");
            var returnLabel        = Expression.Label();
            var locals             = new ParameterExpression[list.Count - 1];
            var labels             = new LabelTarget[list.Count];
            List <Expression> body = new List <Expression>();

            for (int i = 0; i < list.Count - 1; i++)
            {
                var info = list[i];
                locals[i] = Expression.Variable(TypeHelper.GetMemberType(info.Info), info.Info.Name.ToLower());
            }

            for (int i = 0; i < list.Count; i++)
            {
                labels[i] = Expression.Label();
            }
            int j = 0;

            for (int i = 0; i < list.Count; i++)
            {
                var info = list[i];
                var type = TypeHelper.GetMemberType(info.Info);
                if (i < list.Count - 1)
                {
                    var call = Call(i == 0 ? target : locals[i - 1], info, i);
                    body.Add(Expression.Assign(locals[i], call));

                    if (!type.IsValueType || TypeHelper.IsNullable(type))
                    {
                        body.Add(Expression.IfThenElse(Expression.Equal(locals[i], Expression.Constant(null, type)),
                                                       Expression.Return(returnLabel),
                                                       Expression.Label(labels[j++])));
                    }
                }
                else
                {
                    for (int r = list.Count - 1; r >= 0; r--)
                    {
                        info = list[r];
                        type = TypeHelper.GetMemberType(info.Info);
                        if (type.IsValueType || r == list.Count - 1)
                        {
                            var param    = r == 0 ? target : locals[r - 1];
                            var setValue = r == list.Count - 1 ? value : locals[r];

                            if (TypeHelper.CanWrite(info.Info))
                            {
                                var call = Call(param, info, r);
                                body.Add(Expression.Assign(call, setValue));
                            }
                            else
                            {
                                return(null);
                            }
                        }
                    }
                }
            }
            if (j > 0)
            {
                body.Add(Expression.Label(returnLabel));
            }

            return(Expression.Lambda <Action <T, V> >(Expression.Block(locals, body), target, value).Compile());
        }