コード例 #1
0
        protected internal Expression CompileAccessorExpression(Expression target, string clientExpr, Action <List <Expression> > customizeProgression = null, bool liftToNullable = false)
        {
            var progression = new List <Expression> {
                target
            };

            var clientExprItems = clientExpr.Split('.');
            var currentTarget   = target;

            for (var i = 0; i < clientExprItems.Length; i++)
            {
                var clientExprItem = clientExprItems[i];

                if (i == 0 && clientExprItem == "this")
                {
                    continue;
                }

                if (Utils.IsNullable(currentTarget.Type))
                {
                    clientExprItem = "Value";
                    i--;
                }

                if (currentTarget.Type == typeof(ExpandoObject))
                {
                    currentTarget = ReadExpando(currentTarget, clientExprItem);
                }
                else if (DynamicBindingHelper.ShouldUseDynamicBinding(currentTarget.Type))
                {
                    currentTarget = DynamicBindingHelper.CompileGetMember(currentTarget, clientExprItem);
                }
                else
                {
                    currentTarget = Expression.PropertyOrField(currentTarget, clientExprItem);
                }

                progression.Add(currentTarget);
            }

            customizeProgression?.Invoke(progression);

            if (_guardNulls && progression.Count > 1 || liftToNullable && progression.Count > 2)
            {
                var lastIndex = progression.Count - 1;
                var last      = progression[lastIndex];
                if (Utils.CanAssignNull(target.Type) && !Utils.CanAssignNull(last.Type))
                {
                    progression[lastIndex] = Expression.Convert(last, typeof(Nullable <>).MakeGenericType(last.Type));
                }
            }

            return(CompileNullGuard(progression));
        }
コード例 #2
0
        protected internal Expression CompileAccessorExpression(Expression target, string clientExpr, bool forceToString = false)
        {
            if (clientExpr == "this")
            {
                return(target);
            }

            var progression = new List <Expression>();

            progression.Add(target);

            var clientExprItems = clientExpr.Split('.');
            var currentTarget   = target;

            for (var i = 0; i < clientExprItems.Length; i++)
            {
                var clientExprItem = clientExprItems[i];

                if (Utils.IsNullable(currentTarget.Type))
                {
                    clientExprItem = "Value";
                    i--;
                }

                if (DynamicBindingHelper.ShouldUseDynamicBinding(currentTarget.Type))
                {
                    currentTarget = DynamicBindingHelper.CompileGetMember(currentTarget, clientExpr);
                }
                else
                {
                    currentTarget = Expression.PropertyOrField(currentTarget, clientExprItem);
                }

                progression.Add(currentTarget);
            }

            if (forceToString && currentTarget.Type != typeof(String))
            {
                progression.Add(Expression.Call(currentTarget, typeof(Object).GetMethod(nameof(Object.ToString))));
            }

            return(CompileNullGuard(progression));
        }