使用 System.Linq.Expressions 跨越对象数组中的元组 [C#]

Using System.Linq.Expressions to span a tuple in an array of object [C#]

假设我有这样的方法

public static int Sum(int a, int b)
{
    return a + b;
}

我需要构造一个表达式,以便新方法必须以 new object[1]{Sum(a, b);} 的形式返回,为此我使用以下代码:

var callMethod = Expression.Call(mi, parameters);

// new object[] { Sum((a, b) }
var returnResult = Expression.NewArrayInit(
    typeof(object),
    Expression.Convert(callMethod, typeof(object)));

其中 mi 是通过反射获取的 Sum 方法。

现在,我需要扩展表达式的生成以管理作为输出参数的元组,并且元组的结果必须跨越到结果数组中。实际上,我想做的是转换此方法

public static (int result, bool isOverflowed) Sum(int a, int b)
{
    return (a + b, false);
}

进入这个:

 var callMethod = Expression.Call(mi, parameters);

// new object[] { Sum((a, b) }
var returnResult = Expression.NewArrayInit(
    typeof(object),
    Expression.Convert(Tuple1, typeof(object)),  // The desired
    Expression.Convert(Tuple2, typeof(object))); // The desired

如何实现?

由于该方法将 return ValueTuple<int, bool>,因此可以从 Item1Item2 字段中获取值。基本思想是将方法 return 分配给变量并获得 Item1Item2 字段。

var mi = typeof(Program).GetMethod("Sum");
var parameters = new ParameterExpression[]{ Expression.Parameter(typeof(int)), Expression.Parameter(typeof(int)) };
var callMethod = Expression.Call(mi, parameters);
var variable = Expression.Variable(typeof(ValueTuple<int, bool>));
var assign = Expression.Assign(variable, callMethod);
var returnResult = Expression.NewArrayInit(typeof(object),
  Expression.Convert(Expression.Field(variable, "Item1"), typeof(object)),
  Expression.Convert(Expression.Field(variable, "Item2"), typeof(object)));
var block = Expression.Block(new ParameterExpression[] { variable }, assign, returnResult);

var x = Expression.Lambda(block, parameters).Compile().DynamicInvoke(1 , 2);