private object GetValue(object container, MethodCallExpression expression) { var value = container is ValueResult vr ? vr.Value : container; var arguments = expression.Arguments.Select(e => GetValue(container, e)).Select(v => v.Value).ToArray(); var result = expression.Method.Invoke(value, arguments); if (expression.Object == null && expression.Arguments.Any()) { var thisParameter = expression.Arguments.FirstOrDefault(); var thisValue = GetValue(container, thisParameter)?.Value; if (thisValue is IEnumerable extensionEn) { return(ValueResult.EnumerableResult(extensionEn, result)); } } if (value is IEnumerable en) { return(ValueResult.EnumerableResult(en, result)); } return(result); }
private ValueResult GetValue(object container, Expression expression) { var expressionStack = GetExpressionStack(expression); var current = container; while (expressionStack.Any()) { var ex = expressionStack.Pop(); if (ex is LambdaExpression l) { return(ValueResult.Ok(l.Compile())); } else if (ex is MemberExpression m) { if (current is ValueResult vr) { current = GetValue(vr.Value, m); } else { current = GetValue(current, m); } if (current == null && expressionStack.Any()) { return(ValueResult.Null(m.Member.Name)); } } else if (ex is MethodCallExpression met) { current = GetValue(current, met); if (current == null && expressionStack.Any()) { return(ValueResult.Null(met.Method.Name)); } } else if (ex is UnaryExpression u) { if (u.NodeType != ExpressionType.Not) { throw new NotSupportedException($"Only unary expression with NOT is supported: {u.NodeType}"); } if (current is ValueResult vr) { current = new ValueResult { Value = !(bool)vr.Value, Succeeded = !vr.Succeeded, Enumerable = vr.Enumerable, NullPropertyName = vr.NullPropertyName }; } else { current = !(bool)current; } } else if (expression is ConstantExpression c) { current = c.Value; } } if (current is ValueResult r) { return(r); } return(ValueResult.Ok(current)); }