Use LINQ aggregator dynamically

6

I'm trying to create a function to use Linq aggregator functions (sum, average, count) and I'm not succeeding. I have the following code:

    private double AgreggateDynamic<T>(IEnumerable<T> list, string propertyName, string func)
    {            
        //Converter o "array" para uma lista não resolveu
        //IEnumerable<T> listEnum = list.ToList();
        Type enumerableType = typeof(Enumerable);

        MethodInfo sumMethod = typeof(Enumerable).GetMethods().First(
            m => m.Name == func
                && m.IsGenericMethod);

        MethodInfo generic = sumMethod.MakeGenericMethod(enumerableType);

        Func<T, double> expression = x => Convert.ToDouble(x.GetType().GetProperty(propertyName).GetValue(x, null));            
        object[] parametersArray = new object[] { list, expression };

        return Convert.ToDouble(generic.Invoke(null, parametersArray));
    }

    AgreggateDynamic(list, "FooValue", "Sum");

When I run this code snippet, the line return Convert.ToDouble(generic.Invoke(null, parametersArray)); , I get the following error.

  

The object of type 'Manager.Business.Tests.Foo []' can not be converted to type 'System.Collections.Generic.IEnumerable'1 [System.Linq.Enumerable]'.

Any idea what I can do?

    
asked by anonymous 22.01.2016 / 20:24

1 answer

4

See if this solution meets your need:

public static double AgreggateDynamic<T>(IEnumerable<T> list, string propertyName, string func)
{
    Func<T, double> expression = x => Convert.ToDouble(x.GetType().GetProperty(propertyName).GetValue(x, null));

    switch (func.ToLower())
    {
        case "sum": return list.Sum(expression);
        case "average": return list.Average(expression);
        case "count": return list.Count();
        default:
            return 0;
    }
}


static void Main(string[] args)
{
    var list = new []
    {
        new { FooValue = 512313, FooValue2 = 5123 },
        new { FooValue = 512313, FooValue2 = 5123 },
        new { FooValue = 512313, FooValue2 = 5123 },
        new { FooValue = 512313, FooValue2 = 5123 },
    };

    Console.WriteLine("Sum: " + AgreggateDynamic(list, "FooValue", "Sum"));
    Console.WriteLine("Average: " + AgreggateDynamic(list, "FooValue", "Average"));
    Console.WriteLine("Count: " + AgreggateDynamic(list, "FooValue", "Count"));
}
    
13.03.2016 / 17:22