protected static Expression ConvertMethod( MethodCallExpression methodCall, int sourceTypeNumber, SequenceConvertInfo info, ParameterExpression?param, Expression expression) { if (ReferenceEquals(expression, methodCall) && param != null && param.Type != info.Parameter !.Type) { var types = methodCall.Method.GetGenericArguments(); var mgen = methodCall.Method.GetGenericMethodDefinition(); types[sourceTypeNumber] = info.Parameter.Type; var args = methodCall.Arguments.ToArray(); args[0] = info.Expression; for (var i = 1; i < args.Length; i++) { var arg = args[i].Unwrap(); if (arg.NodeType == ExpressionType.Lambda) { var l = (LambdaExpression)arg; if (l.Parameters.Any(a => ReferenceEquals(a, param))) { args[i] = Expression.Lambda( l.Body.Transform( (methodCall, sourceTypeNumber, info, param),
protected static Expression ConvertMethod( MethodCallExpression methodCall, int sourceTypeNumber, SequenceConvertInfo info, ParameterExpression param, Expression expression) { if (string.ReferenceEquals(expression, methodCall) && param != null && param.Type != info.Parameter.Type) { var types = methodCall.Method.GetGenericArguments(); var mgen = methodCall.Method.GetGenericMethodDefinition(); types[sourceTypeNumber] = info.Parameter.Type; var args = methodCall.Arguments.ToArray(); args[0] = info.Expression; for (var i = 1; i < args.Length; i++) { var arg = args[i].Unwrap(); if (arg.NodeType == ExpressionType.Lambda) { var l = (LambdaExpression)arg; if (l.Parameters.Any(a => string.ReferenceEquals(a, param))) { args[i] = Expression.Lambda( l.Body.Transform(ex => ConvertMethod(methodCall, sourceTypeNumber, info, param, ex)), info.Parameter); return(Expression.Call(methodCall.Object, mgen.MakeGenericMethod(types), args)); } } } } if (expression == methodCall.Arguments[0]) { return(info.Expression); } switch (expression.NodeType) { case ExpressionType.Parameter: if (info.ExpressionsToReplace != null) { foreach (var item in info.ExpressionsToReplace) { if (expression == item.Path || expression == param && item.Path.NodeType == ExpressionType.Parameter) { return(item.Expr); } } } break; case ExpressionType.MemberAccess: if (info.ExpressionsToReplace != null) { foreach (var item in info.ExpressionsToReplace) { var ex1 = expression; var ex2 = item.Path; while (ex1.NodeType == ex2.NodeType) { if (ex1.NodeType == ExpressionType.Parameter) { return(ex1 == ex2 || info.Parameter == ex2? item.Expr : expression); } if (ex2.NodeType != ExpressionType.MemberAccess) { break; } var ma1 = (MemberExpression)ex1; var ma2 = (MemberExpression)ex2; if (ma1.Member != ma2.Member) { break; } ex1 = ma1.Expression; ex2 = ma2.Expression; } } } break; } return(expression); }
protected static Expression ConvertMethod( MethodCallExpression methodCall, int sourceTypeNumber, SequenceConvertInfo info, ParameterExpression param, Expression expression) { if (string.ReferenceEquals(expression, methodCall) && param != null && param.Type != info.Parameter.Type) { var types = methodCall.Method.GetGenericArguments(); var mgen = methodCall.Method.GetGenericMethodDefinition(); types[sourceTypeNumber] = info.Parameter.Type; var args = methodCall.Arguments.ToArray(); args[0] = info.Expression; for (var i = 1; i < args.Length; i++) { var arg = args[i].Unwrap(); if (arg.NodeType == ExpressionType.Lambda) { var l = (LambdaExpression)arg; if (l.Parameters.Any(a => string.ReferenceEquals(a, param))) { args[i] = Expression.Lambda( l.Body.Transform(ex => ConvertMethod(methodCall, sourceTypeNumber, info, param, ex)), info.Parameter); return Expression.Call(methodCall.Object, mgen.MakeGenericMethod(types), args); } } } } if (expression == methodCall.Arguments[0]) return info.Expression; switch (expression.NodeType) { case ExpressionType.Parameter : if (info.ExpressionsToReplace != null) foreach (var item in info.ExpressionsToReplace) if (expression == item.Path || expression == param && item.Path.NodeType == ExpressionType.Parameter) return item.Expr; break; case ExpressionType.MemberAccess : if (info.ExpressionsToReplace != null) { foreach (var item in info.ExpressionsToReplace) { var ex1 = expression; var ex2 = item.Path; while (ex1.NodeType == ex2.NodeType) { if (ex1.NodeType == ExpressionType.Parameter) return ex1 == ex2 || info.Parameter == ex2? item.Expr : expression; if (ex2.NodeType != ExpressionType.MemberAccess) break; var ma1 = (MemberExpression)ex1; var ma2 = (MemberExpression)ex2; if (ma1.Member != ma2.Member) break; ex1 = ma1.Expression; ex2 = ma2.Expression; } } } break; } return expression; }