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)); }
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)); }