【发布时间】:2023-03-05 06:03:02
【问题描述】:
在我这几天使用表达式树的过程中,我遇到了一些我觉得很难理解的东西;希望有人能够在这里有所启发。
如果您编写Expression<Func<dynamic, dynamic>> expr1 = x => 2 * x; 代码,编译器会报错,您将一事无成。但是,似乎如果您通过一种方法创建一个这样的表达式,那么编译器似乎对此很满意,并且生成的应用程序可以正常工作。这没有意义,所以我想知道窗帘后面发生了什么。
我想,在后台,ConvertExpression 返回的表达式可能是Expression<Func<object, object>> 类型,这是一个有效类型,但令我困惑的是我不能在声明中使用Expression<Func<dynamic, 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;
}
}
【问题讨论】:
-
表达式树中的动态 - 解决方案在这里:http://stackoverflow.com/questions/3562088/c-4-dynamic-in-expression-trees
标签: c# dynamic .net-4.0 lambda expression-trees