在我工作几天的表情树之前,我遇到了一些难以理解的东西;希望有人能够在这里散发一些光.
如果您编写Expression< Func< dynamic,dynamic>> expr1 = x => 2 * x;编译器会抱怨,你不会得到任何地方.然而,似乎如果您通过一个方法创建一个这样的表达式,那么编译器似乎对它很满意,并且生成的应用程序的工作原理.这没有意义,所以我想知道窗帘后面会发生什么.
我想,在引擎盖下,ConvertExpression返回的表达式可能是Expression< Func< object,object>类型,它是一个有效的类型,但是它使我无法使用Expression&Func< dynamic,动态>>键入一个声明,但我可以使用它作为方法的返回类型.见下面的例子. 非常感谢!
public class ExpressionExample { public void Main() { // Doesn't compile: //Expression<Func<dynamic,dynamic>> expr1 = x => 2 * x; // Compiles and works - OK Expression<Func<double,double>> expr2 = x => 2 * x; Func<double,double> func2 = (Func<double,double>)expr2.Compile(); Console.WriteLine(func2(5.0).ToString()); // Outputs 10 // Compiles and works - ??? This is the confusing block... Expression<Func<dynamic,dynamic>> expr3 = ConvertExpression(expr2); Func<dynamic,dynamic> func3 = (Func<dynamic,dynamic>)expr3.Compile(); Console.WriteLine(func3(5.0).ToString()); // Outputs 10 // Side note: compiles and works: Expression<Func<object,object>> expr4 = x => double.Parse(2.ToString()) * double.Parse(x.ToString()); Func<object,object> func4 = (Func<object,object>)expr4.Compile(); Console.WriteLine(func4(5.0).ToString()); // Outputs 10 } private Expression<Func<dynamic,dynamic>> ConvertExpression<TInput,TOutput>(Expression<Func<TInput,TOutput>> expression) { Expression<Func<object,TInput>> convertToInput = value => (TInput)value; // The following doesn't compile: var input = Expression.Parameter(typeof(dynamic),"input"); var input = Expression.Parameter(typeof(object),"input"); Expression<Func<TOutput,dynamic>> convertToOutput = value => (dynamic)value; var body = Expression.Invoke(convertToOutput,Expression.Invoke(expression,Expression.Invoke(convertToInput,input))); var lambda = Expression.Lambda<Func<dynamic,dynamic>>(body,input); return lambda; } }
解决方法
I suppose that,under the hood,the expression returned by ConvertExpression is perhaps of type
Expression<Func<object,object>>
,which is a valid type
正确.
I can’t use
Expression<Func<dynamic,dynamic>>
type in a declaration and yet I can use it as the return type of a method.
声明的这一部分是不正确的.正如您在示例中注意到的那样,在本地变量的声明中使用该类型是完全合法的.
不合法的位是在转换为表达式树类型的lambda中执行动态操作.具体表达式树型不相关;重要的是操作是动态的.