C# Can';t使用表达式初始化LambdaExpression
问题类似于,但更具体和公认的答案不适合我的需要 这很好:C# Can';t使用表达式初始化LambdaExpression,c#,lambda,expression-trees,C#,Lambda,Expression Trees,问题类似于,但更具体和公认的答案不适合我的需要 这很好: Expression<Func<object, object>> specificExpression = (object o) => new object(); Expression generalExpression = specificExpression; 报告的编译错误: 无法将lambda表达式转换为类型“System.Linq.Expressions.expression”,因为它不是委托类型
Expression<Func<object, object>> specificExpression = (object o) => new object();
Expression generalExpression = specificExpression;
报告的编译错误:
无法将lambda表达式转换为类型“System.Linq.Expressions.expression”,因为它不是委托类型
表达式
源自表达式
现在我有了一个框架,其中的方法可以接受各种表达式,即typeExpression
。在每个方法调用中,被迫显式地将lambda强制转换为相应的表达式
,这令人沮丧
在这种情况下,这种基本OOP行为被破坏的原因有哪些?转换不起作用,因为编译器无法推断您试图创建的特定表达式类型。如果是你干的呢
Expression generalExpression = (object o) => "foo";
这应该是一个表达式吗?那表达式
或表达式
呢?这些类型都是表达式树的有效最终类型,编译器不会假装知道您要做什么
您需要转换特定类型,以通知编译器要生成哪种类型的表达式:
Expression generalExpression = (Expression<Func<object, object>>)
(object o) => new object();
这是操作
,还是线程启动
,还是其他类型的无参数无效返回委托?当您编写
Expression specificExpression=(object o)=>new object()代码>
实际上,C#编译器为我们提供了一种易于编写的方法
此表达式实际上将编译为如下内容:
Expression.Lambda<Func<object, object>> specificExpression = Expression.Lambda<Func<object,object>> ( ... )
Expression.Lambda specificExpression=Expression.Lambda(…)
正如您所看到的,表达式
不是委托类型,即使第一个表达式可能导致我们出错,让我们相信这是事实
“Expression”不是委托类型,因此您不能直接将其指定为委托对象,因为编译器不提供编写的方便性(就像Expression
类那样)
很抱歉这么说,但你必须走令人沮丧的路
RianaC#编译器将表达式计算为最不复杂的形式,例如:
var x = (object o) => new object();
x
应该是Func
,而不是表达式
。在这种情况下,编译器确定该值为委托,并且由于表达式
不能接受委托(只有表达式
/表达式
类型可以接受委托),因此会引发编译器错误
另外,请参阅@Riana的答案,因为表达式形式实际上是由编译器重写的。如果遵循此逻辑,则var
关键字应始终生成编译时错误var o=“abc”
可以是对象,不是吗?某种程度上,类型推断与var
一起工作,所有信息实际上都在我的示例中提供(可以推断参数类型和返回类型)。var
是专门定义的,用于声明一个变量属于表达式右侧求值的任何类型。在这种情况下,编译器甚至还不知道表达式的右边是什么!它可以是任何委托类型或任何表达式类型。在这种情况下,编译器可以使用“预期类型”来确定如何处理右侧,但如果使用var
或Delegate
或Expression
作为左侧类型,则编译器没有足够的信息来解析右侧表达式的类型。换句话说,通过将lambda分配给Expression
类型的变量,编译器可以将该提示解析为表达式树,该表达式树接受对象
,并返回对象
。但是,如果您分配给Expression
类型的变量,则该变量包含的有用信息不足,编译器无法理解lambda需要转换为什么类型。lambda编译为表达式或委托的部分让我信服!但是,为什么lambda不总是编译成表达式仍然是个谜(好吧,也许是为了方便委托?)。如果是的话,我坚持认为可以推断出精确的(最佳匹配)表达式类型。实际上,尝试var
方法会生成编译错误无法将lambda表达式分配给隐式类型的局部变量
。这将产生错误,原因与委托x=(对象o)=>newobject()相同
将给出一个错误--没有足够的上下文信息供编译器确定要创建的委托/表达式的类型。我假定您的意思是:expression specificExpression=expression.Lambda(…)
如果是,那么它就是有用的信息。但是,Expression generalExpression=Expression.Lambda(…)
仍然可以正常工作,这就是我想要的。。。
Expression.Lambda<Func<object, object>> specificExpression = Expression.Lambda<Func<object,object>> ( ... )
var x = (object o) => new object();