动态Lambda表达式构建器在枚举时崩溃

4
为了能够动态地在LINQ中使用字符串,我使用了以下辅助函数来构建Lambda表达式:
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();
        }

我将在下面的示例中解释这个函数的工作原理:我有一个名为Person的类,它有三个属性:

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

enum EnumerateType {
   Normal = 1,
   Premium = 2
}

然后,在一个 Person 列表中,我会使用我的辅助函数按任意属性排序,方式如下:

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();

使用名称和年龄属性时,它可以正常工作,但是使用类型属性时,在辅助函数的“var mySortExpression = Expression.Lambda>(Expression.Property(param, field), param);”执行时会引发以下异常:
Cannot use a expression of type 'EnumerateType' for the returned value type 'System.Object'

为什么会这样呢?为了能够为枚举创建lambda表达式(我认为枚举内部是整数),我应该怎么做才能解决它呢?
谢谢。
编辑:我注意到它也会崩溃任何 DateTime 属性。

你尝试过 https://dev59.com/nnVD5IYBdhLWcg3wQJKT#233505 吗? - Marc Gravell
1个回答

2

实际上,Age 也失败了:

类型为 'System.Int32' 的表达式不能用于返回类型 'System.Object'

问题在于你需要将值类型转换(在这种情况下是一个装箱)为一个 object

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

然而,在这里使用object本身可能存在问题。我建议查看Dynamic LINQ OrderBy on IEnumerable<T>


感谢@MarcGravell的回答,通过转换我解决了异常问题。我正在尝试使用您的动态LINQ方法,但我的VS无法识别ApplyOrder函数。我在哪里可以找到所需的引用?谢谢。 - David Jiménez Martínez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接