繁体   English   中英

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

[英]Expression of type 'System.Int64' cannot be used for return type 'System.Object'

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

e => e.CreationDate;

CreationDate的类型为long ,但我希望表达式返回一个object

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

> entities?order=creationDate
> entities?order=score

如您所见,我可以使用不同类型的不同属性进行排序,因此返回类型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);

我得到以下异常:

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

这工作正常,但它不会生成我想要的表达式。 相反,它生成这样的东西:

e => Convert(e.CreationDate)

我不能使用这个解决方案,因为如果表达式主体不是MemberExpression (即成员访问操作),程序后面会抛出异常

我一直在互联网上搜索一个令人满意的答案,但找不到任何答案。

如何在返回类型为object e => e.CreationDate下实现e => e.CreationDate

根据您使用result您可以使用委托类型Func<Entity, long>动态创建它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);

简答:不,这是不可能的。 需要将值类型加框以将其视为对象。 编译器通常会为您执行此操作,但如果您自己构建代码(例如表达式树),则需要将其指定为显式转换,就像您在找到的答案中看到的那样。 如果您不能将它作为非泛型的LambdaExpression,我会在您期望MemberExpression或使用PropertyInfo的情况下另外处理转换情况,并仅在最后一刻构造orderby Expression。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM