private Maybe<Expression> ParseEnumerableMethods(Expression instance, Type elementType, string methodName,
Lazy<Expression[]> parseArgumentList)
{
ParameterExpression outerIt = _it;
ParameterExpression innerIt = Expression.Parameter(elementType, "Param" + _paramCounter++);
_it = innerIt;
Expression[] args = parseArgumentList.Value;
_it = outerIt;
MethodBase signature;
var typeArgs = new[] { elementType };
if (methodName.EqualsIgnoreCase("Avg"))
{
methodName = "Average";
}
if (GetAppropriateMethodCount(typeof(IEnumerableAggregateSignatures), methodName, false, args, out signature) == 1)
{
if (signature.Name == "Min" || signature.Name == "Max")
{
typeArgs = new[] { elementType, args[0].Type };
}
args = args.Length == 0 ? new[] { instance } : new[] { instance, Expression.Lambda(args[0], innerIt) };
return Expression.Call(typeof(Enumerable), signature.Name, typeArgs, args);
}
if (args.Length == 0)
return Maybe.Nothing;
var methodInfo = GetEnumerableMethod(methodName, new[] { elementType, args[0].Type });
if (methodInfo == null)
return Maybe.Nothing;
var method = Expression.Call(methodInfo, instance, Expression.Lambda(args[0], innerIt));
return method;
}