gpt4 book ai didi

c# - 编译表达式抛出不能用于返回类型 ArgumentException

转载 作者:太空宇宙 更新时间:2023-11-03 22:58:06 27 4
gpt4 key购买 nike

我正在尝试更加熟悉表达式树。

我创建了一个简单的 switch 表达式,如下所示:

var paramExp = Expression.Parameter(typeof(int));
Expression<Func<int>> defaultBodyExp = () => 4;
var switchBodyExp = Expression.Switch(paramExp, defaultBodyExp,
Expression.SwitchCase(defaultBodyExp, Expression.Constant(1)));
var func = Expression.Lambda<Func<int, int>>(switchBodyExp, paramExp).Compile();
int result = func(6);

但这会在尝试调用 Compile 时引发以下异常:

Expression of type 'System.Func`1[System.Int32]' cannot be used for return type 'System.Int32'

我可以通过执行以下操作让它工作:

var paramExp = Expression.Parameter(typeof(int));
//Expression<Func<int>> defaultBodyExp = () => 4;
var defaultBodyMethodInfo = typeof(Program).GetMethod("DefaultBody");
var switchBodyExp = Expression.Switch(paramExp, Expression.Call(defaultBodyMethodInfo),
Expression.SwitchCase(Expression.Call(defaultBodyMethodInfo), Expression.Constant(1)));
var func = Expression.Lambda<Func<int, int>>(switchBodyExp, paramExp).Compile();
int result = func(6);

public static int DefaultBody()
{
return 4;
}

但我真的不确定为什么我的第一个例子不起作用,我很想知道如何正确地做到这一点,这样我就不必像第二个例子那样声明一个方法。我是否需要像第二个示例中那样进行某种调用调用?

我看过 SO 上其他一些类似的答案,但我对表达式树还不够熟悉,所以我真的不确定它们是否能回答我的问题。

最佳答案

lambda 表达式 Expression<Func<int>>只能在需要Func<int>的地方直接使用(如 Enumerable.Select )或 Expression<Func<int>> (类似于 Queryable.Select ,但您需要将其包裹在 Expression.Quote 中)。

为了在预期的地方使用它int就像您的情况一样,它需要转换为表示 lambda 表达式“执行”结果的表达式。让我们把原来的代码改成

Expression<Func<int>> defaultBodyLambda = () => 4;
var defaultBodyExp = ???;

问题是应该???是。

一种可能的(也是通用的)解决方案是使用 Expression.Invoke 方法:

var defaultBodyExp = Expression.Invoke(defaultBodyLambda);

或者,由于这个特定的 lambda 表达式没有参数,我们可以简单地使用 LambdaExpression.Body 属性:

var defaultBodyExp = defaultBodyLambda.Body;

关于c# - 编译表达式抛出不能用于返回类型 ArgumentException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44417490/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com