我试图从不同的结构构建表达式树。为方便起见,我们称之为结构S.我遇到了一个问题。我必须能够在S中根据S指定的输入和输出类型构建LambdaExpression
。 S指定表达式本身和LambdaExpression
的签名(例如Func<int, int>, Func<bool, string, int>
等)。因为在构建表达式时我可以使用非泛型Expression.Lambda(...)
,所以我可以放心地忽略签名。但是当表达式具有递归调用时它不起作用。我必须预先将表达式存储在Expression.Variable(typeof(Func<...>))
中以供将来调用。但我不知道编译时的类型,因为我将S作为数据,它完全是运行时的东西。
以下是示例:
public class Structure
{
public Parameter[] InputParams { get; set; }
public Parameter OutputParam { get; set; }
public Graph Expression { get; set; }
}
public class Parameter
{
public string Name { get; set; }
public string Type { get; set; }
}
public class Builder
{
public static Expression Build(Structure s)
{
var inputParams = new ParameterExpression[s.InputParams.Length];
int index = 0;
foreach (var param in s.InputParams)
{
inputParams[index++] = Expression.Parameter(Utils.GetDataType(param.Type), param.Name);
}
ParameterExpression delegVar = Expression.Variable(typeof(Func<int, int>), "sum"); // here types of Func must be taken from S
LambdaExpression expression = Expression.Lambda(
Expression.Block(
new[] { delegVar },
Expression.Assign(delegVar,
Expression.Lambda(
Expression.Block(
// some work is done here
Expression.Invoke(delegVar, inputParams)
),
inputParams
)
),
Expression.Invoke(delegVar, inputParams)
),
inputParams
);
return expression;
}
}
请忽略表达式将在运行时抛出StackOverflowException的事实。
答案 0 :(得分:1)
经过在互联网上的广泛搜索后,我终于能够解决问题了。我所做的是创建了一个类型定义,并通过传递类型参数从中创建了泛型类型。这是解决方案。
performSegue(withIdentifier: "segueToMain", sender: self)
编辑:我的解决方案很糟糕。正如Ivan Stoev提到的那样,有一种方法正是为了这个目的。它是Expression.GetFuncType