4

In order to be able to dynamically use strings in LINQ, I use the following helper function I built in order to construct a Lambda expression from a string:

public static Func<ObjectToOrder, object> GetSortExpression<ObjectToOrder> (string field) {
            var param = Expression.Parameter(typeof(ObjectToOrder), "objectToOrder");
            var mySortExpression = Expression.Lambda<Func<ObjectToOrder, object>>(Expression.Property(param, field), param);
            return mySortExpression.Compile();
        }

I'll explain how this function works in the following example: I have a class Person with three of attributes:

class Person {
    public string Name {get;set;}
    public int Age {get;set;}
    public EnumerateType Type {get;set;}
}

enum EnumerateType {
   Normal = 1,
   Premium = 2
}

Then inside a List of Person, I would use my helper function to order by any attribute this way:

List<Person> people = new List<Person>();
//Create people in the list
//...
people = people.OrderBy(GetSortExpression<Person>("Name")).ToList();
people = people.OrderBy(GetSortExpression<Person>("Age")).ToList();
people = people.OrderBy(GetSortExpression<Person>("Type")).ToList();

With the attributes Name and Age it works fine, but with the Type attribute it raises the following exception when executing "var mySortExpression = Expression.Lambda>(Expression.Property(param, field), param);" of the helper function:

Cannot use a expression of type 'EnumerateType' for the returned value type 'System.Object'

Why is that so? What should I do in order to solve it and be able to create a lambda expression for enumerates (I thought internally enumerates are integers)?

Thank you

EDIT: I've noted that it also crashes with any DateTime attribute.

David Jiménez Martínez
  • 3,053
  • 5
  • 23
  • 43

1 Answers1

2

Actually, it fails for Age too:

Expression of type 'System.Int32' cannot be used for return type 'System.Object'

The immediate issue is that you need a conversion (a box in this case) from a value-type to an object:

var mySortExpression = Expression.Lambda<Func<ObjectToOrder, object>>(
    Expression.Convert(
        Expression.Property(param, field),
        typeof(object)
    ), param);

However, using object here could in-and-of-itself be problematic. I suggest looking at Dynamic LINQ OrderBy on IEnumerable<T>

Community
  • 1
  • 1
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Thanks @MarcGravell for your answer, with the conversion I could solve the Exception issue. I am trying your dynamic LINQ methods, yet my VS doesn't recognize the function ApplyOrder. Where could I find the required reference? thank you – David Jiménez Martínez Dec 04 '13 at 10:42