“System.Int64”类型的表达式不能用于返回类型“System.Object”

Mat*_*ero 5 .net c# linq reflection expression-trees

我正在尝试创建以下形式的表达式:

e => e.CreationDate;
Run Code Online (Sandbox Code Playgroud)

CreationDate类型为long,但是我希望表达式返回 an object

我想用作object返回类型,因为表达式是在运行时根据查询参数动态构建的。查询参数指定表达式中要访问的属性,例如:

> entities?order=creationDate
> entities?order=score
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我可以按不同类型的不同属性进行排序,因此返回类型object将允许我构建尽可能通用的表达式。

问题是当我尝试创建表达式时:

ParameterExpression entityParameter = Expression.Parameter(typeof(Entity), "e");
Expression propertyAccess = Expression.Property(entityParameter, property);
Expression<Func<Entity, object>> result = Expression.Lambda<Func<Entity, object>>(propertyAccess, entityParameter);
Run Code Online (Sandbox Code Playgroud)

我得到以下异常:

“System.Int64”类型的表达式不能用于返回类型“System.Object”

这很奇怪,因为据我所知,所有类型都扩展自object(表达式树似乎尚不支持多态性)。

尽管如此,我在网上搜索并偶然发现了这个类似的问题:

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

根据Jon Skeet的回答,我将最后一行修改为:

Expression<Func<Entity, object>> result = Expression.Lambda<Func<Entity, object>>(Expression.Convert(propertyAccess, typeof(object)), entityParameter);
Run Code Online (Sandbox Code Playgroud)

这工作正常,但它不会生成我想要的表达式。相反,它会生成如下内容:

e => Convert(e.CreationDate)
Run Code Online (Sandbox Code Playgroud)

我无法使用此解决方案,因为稍后在程序中,如果表达式主体不是 a MemberExpression(即成员访问操作),则会引发异常

我一直在互联网上寻找令人满意的答案,但没有找到。

我怎样才能实现e => e.CreationDate返回类型的位置object

Lee*_*Lee 2

根据您的使用方式,result您可以使用委托类型动态创建它Func<Entity, long>并将其键入为LambdaExpression

ParameterExpression entityParameter = Expression.Parameter(typeof(Entity), "e");
Expression propertyAccess = Expression.Property(entityParameter, property);
var funcType = typeof(Func<,>).MakeGenericType(typeof(Entity), property.PropertyType);
LambdaExpression result = Expression.Lambda(funcType, propertyAccess, entityParameter);
Run Code Online (Sandbox Code Playgroud)