无法使用表达式初始化 LambdaExpression
问题类似于 John K 的 one by John K,但更具体,并且接受的答案并不不适合我的需要。
这编译得很好:
Expression<Func<object, object>> specificExpression = (object o) => new object();
Expression generalExpression = specificExpression;
而这个则不然:
Expression generalExpression = (object o) => new object();
报告编译错误:
无法将 lambda 表达式转换为类型“System.Linq.Expressions.Expression”,因为它不是委托类型
Expression
派生自Expression
。
现在我有一个框架,其中的方法接受各种表达式,即类型Expression
。在每个方法调用上被迫将 lambda 显式转换为相应的 Expression
是令人沮丧的。
在这种情况下,有什么好的理由可以解释为什么这种基本的 OOP 行为会被破坏吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
转换不起作用,因为编译器无法推断您正在尝试创建哪种特定表达式类型。如果你这样做了怎么办?
这应该是
Expression>
吗?Expression>
或Expression>
怎么样?这些类型都是表达式树的有效最终类型,并且编译器不会假装知道您要做什么。您需要通过特定类型进行转换,以通知编译器您想要生成哪种类型的表达式:
如果您尝试这样做,您会看到类似的编译器错误:
Is that an
Action
, or aThreadStart
,或其他类型的无参数无效返回委托?The conversion doesn't work because the compiler cannot infer which specific expression type you are trying to create. What if you did this?
Should this be an
Expression<Func<object, string>>
? What aboutExpression<Func<object, object>>
orExpression<Func<object, IComparable>>
? These types would all be a valid final type for the expression tree, and the compiler doesn't pretend to know what you are trying to do.You need to cast through the specific type to inform the compiler which type of expression you want to produce:
You would see a similar compiler error if you tried this:
Is that an
Action
, or aThreadStart
, or some other kind of no-argument void-returning delegate?当您编写
Expression> 时,具体表达式 = (对象 o) => new object();
这实际上是 C# 编译器为我们提供的一种易于编写的方法。
这个表达式实际上会被编译成这样的:
正如你所看到的,
Expression>
不是委托类型,即使第一个表达式可能会导致我们出错并且让我们相信情况确实如此。“Expression”不是委托类型,因此您不能直接将其分配为委托对象,因为编译器不提供编写的便利性(与
Expression
类一样)。很抱歉这么说,但你必须走这条令人沮丧的路。
瑞安娜
When you write
Expression<Func<object, object>> specificExpression = (object o) => new object();
It is actually an ease of writing that the C# compiler offers to us.
This expression will actually be compiled to something like this :
and as you can see,
Expression<Func<object,object>>
is not a delegate type even if the first expession could induce us in error and let us believe that this is the case."Expression" is not of delegate type, so you can't assign it directly a delegate object because the compiler doesn't offer the ease of writing (as it does for
Expression<T>
classes).Sorry to say that but you have to go the frustrating way.
Riana
C# 编译器将表达式计算为最简单的复杂形式,例如:
x
应该是Func
,而不是Expression>
。在这种情况下,编译器确定该值是委托,并且由于Expression
无法接受委托(仅Expression>>
/Expression
类型即可),则抛出编译器错误。另外,请参阅@Riana的答案,因为表达式形式实际上是由编译器重写的。
The C# compiler evaluates the expression to the least complex form, for example:
x
should be aFunc<object, object>
, not anExpression<Func<object, object>>
. In this case, the compiler is determining the value is a delegate, and sinceExpression
cannot take a delegate (only theExpression<Func<>>
/Expression<Action>
types can), the compiler error is thrown.Also, see @Riana's answer, because the expression form is actuall rewritten by the compiler.