打印传递给 Func 对象的 lambda
Print the lambda passed to a Func object
我可以像这样打印 lambda 表达式
Expression<Func<double,double>> expr = x => x * x;
string s = expr.ToString(); // "x => (x * x)"
但是如果
Func<double, double> function = x => x * x;
那么我怎样才能生成 Expression<Func<double,double>>
来产生相同的结果呢? Expression 构造函数是内部的,Func 类型和它们的 Expression 之间没有隐式转换。
你不能。
当你写:
Expression<Action<int>> e = x => Console.WriteLine(x);
编译器发出(简化):
ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "x");
MethodInfo method = typeof(Console).GetMethod("WriteLine", new[] { typeof(object) });
MethodCallExpression body = Expression.Call(null, method, parameterExpression);
Expression<Action<int>> e = Expression.Lambda<Action<int>>(body, parameterExpression);
看看它实际上是如何发出在运行时重新创建表达式树的代码的?
相比之下,当你写:
Action<int> a = x => Console.WriteLine(x);
编译器发出(简化)
internal void GeneratedMethod(int x)
{
Console.WriteLine(x);
}
...
Action<int> a = new Action<int>(GeneratedMethod);
看出区别了吗?运行时根本无法采用已编译的方法并为其创建表达式树。
构造表达式树的唯一方法是使用 Expression
class 上的方法从各个部分构建它。如果您使用 lambda,编译器会巧妙地发出在运行时执行此操作的代码。但是,您不能从 compiled 方法开始。
参见 SharpLab 上的示例。
我可以像这样打印 lambda 表达式
Expression<Func<double,double>> expr = x => x * x;
string s = expr.ToString(); // "x => (x * x)"
但是如果
Func<double, double> function = x => x * x;
那么我怎样才能生成 Expression<Func<double,double>>
来产生相同的结果呢? Expression 构造函数是内部的,Func 类型和它们的 Expression 之间没有隐式转换。
你不能。
当你写:
Expression<Action<int>> e = x => Console.WriteLine(x);
编译器发出(简化):
ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "x");
MethodInfo method = typeof(Console).GetMethod("WriteLine", new[] { typeof(object) });
MethodCallExpression body = Expression.Call(null, method, parameterExpression);
Expression<Action<int>> e = Expression.Lambda<Action<int>>(body, parameterExpression);
看看它实际上是如何发出在运行时重新创建表达式树的代码的?
相比之下,当你写:
Action<int> a = x => Console.WriteLine(x);
编译器发出(简化)
internal void GeneratedMethod(int x)
{
Console.WriteLine(x);
}
...
Action<int> a = new Action<int>(GeneratedMethod);
看出区别了吗?运行时根本无法采用已编译的方法并为其创建表达式树。
构造表达式树的唯一方法是使用 Expression
class 上的方法从各个部分构建它。如果您使用 lambda,编译器会巧妙地发出在运行时执行此操作的代码。但是,您不能从 compiled 方法开始。
参见 SharpLab 上的示例。