danyolgiax
danyolgiax

Reputation: 13096

List of dynamic objects with dynamic groupBy

I need to achieve something like this but I cannot figure how to make it work:

class Program
{
    static List<dynamic> myList = new List<dynamic>();

    static void Main(string[] args)
    {
        myList.Add(new { Test = "test", Test2 = "test2" });
        myList.Add(new { Test = "test", Test2 = "test2" });
        myList.Add(new { Test = "test1", Test2 = "test2" });

        // I need to pass a dynamic list of expression like:
        GenerateGroup<dynamic>(x=>x.Test, x => x.Test2); //groups myList in 2 groups
        GenerateGroup<dynamic>(x=>x.Test2); //groups myList in a single group
    }

    private static void GenerateGroup<T>(params Expression<Func<T, object>>[] properties)
    {
       //I need to group for the properties passed as parameters
       var result= myList.GroupBy(properties);
    }
}

I receive compiler errors:

An expression tree may not contain a dynamic operation

This is only an example of a complex application but at the end, I need to use a list of dynamics and I need to group them with a dynamic list of properties. This is because I read data/properties from multiple PDF sources and it's not possible to use static classes.

Is it possible to fix this error or it is a compiler limitation and I need to approach the problem in another way?

UPDATE

I think I've made a step forward thanks to your answers:

class Program
{
    static List<dynamic> myList = new List<dynamic>();

    static List<Foo> myListFoo = new List<Foo>();


    static void Main(string[] args)
    {
        myList.Add(new { Test = "test", Test2 = "test2" });
        myList.Add(new { Test = "test", Test2 = "test2" });
        myList.Add(new { Test = "test1", Test2 = "test2" });


        myListFoo.Add(new Foo { MyProperty =1});

        GenerateGroup<dynamic>(x =>new  {  x.Test,  x.Test2});

        GenerateGroup<Foo>(x=>x.MyProperty);
    }

    private static void GenerateGroup<T>(Func<T, object> properties)
    {
       var result= myList.GroupBy(properties);

        result = myListFoo.GroupBy(properties);
    }
}

public class Foo
{
    public int MyProperty { get; set; }
}

and I have only a compilation error on groupBy:

'List<dynamic>' does not contain a definition for 'GroupBy' and the best extension method overload 'ParallelEnumerable.GroupBy<T, object>(ParallelQuery<T>, Func<T, object>)' requires a receiver of type 'ParallelQuery<T>'

Upvotes: 2

Views: 947

Answers (1)

Camilo Terevinto
Camilo Terevinto

Reputation: 32088

You need to make some changes to your code:

  • Expression<Func<,>> is not what you are looking for, the Where overloads accepted by IEnumerable<T> all use Func<,>
  • There's no reason to make GenerateGroup generic if you are going to hard-code dynamic
  • Instead of passing multiple parameters, you should create an object that includes the data you want to group by

If you mix all those points, you should end up with something like this:

static void Main(string[] args)
{
    myList.Add(new { Test = "test", Test2 = "test2" });
    myList.Add(new { Test = "test", Test2 = "test2" });
    myList.Add(new { Test = "test1", Test2 = "test2" });

    // I need to pass a dynamic list of expression like:
    GenerateGroup(x => new { x.Test, x.Test2 } ); //groups myList by Test and Test2
    GenerateGroup(x => x.Test2); //groups myList in a single group
}

private static void GenerateGroup(Func<dynamic, object> groupper)
{
    var groupped = myList.GroupBy(groupper);
}

Upvotes: 3

Related Questions