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”,因为它不是委托类型

表达式
源自
表达式

现在我有了一个框架,其中的方法可以接受各种表达式,即type
Expression
。在每个方法调用中,被迫显式地将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
类那样)

很抱歉这么说,但你必须走令人沮丧的路

Riana

C#编译器将表达式计算为最不复杂的形式,例如:

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