![](/img/trans.png)
[英]Expression of type 'System.Int32' cannot be used for return type '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.