使用表达式[]调用(params对象[])

本文关键字:params 对象 调用 表达式 | 更新日期: 2023-09-27 17:57:30

我正试图在Linq.Expression树中用调用String.Format。这里有一个快速的例子:

    var format = Expression.Constant("({0}) {1}");
    var company = Expression.Property(input, membernames.First());
    var project = Expression.Property(input, membernames.Last());
    var args = new Expression[] {format, company, project};
    var invoke = Expression.Call(method,args);

然而,问题是String.Format的签名是:

String.Format(string format, params object[] args)

我正试图传入表达式[]。

现在我可以经历创建一个数组的所有麻烦,用表达式的结果填充它,但我真正想要的结果是这样的:

String.Format("({0}) {1}", input.foo, input.bar)

如何通过Linq表达式调用params函数?

使用表达式[]调用(params对象[])

params实际所做的只是为该参数指定ParamArrayAttribute。C#编译器理解这一点,并在幕后创建数组。

表达式不理解这一点,所以如果要用params调用方法,实际上必须自己创建数组。这也可以从以下事实中看出:当您使用params-方法将lambda分配给表达式时,该表达式包含数组创建:

Expression<Func<string>> expression = () => string.Format("",1,2,3,4);
string expressionString = expression.ToString();

这里,expressionString将包含以下字符串:

() => Format("", new [] {Convert(1), Convert(2), Convert(3), Convert(4)})

要创建用于创建数组的表达式,请使用Expression.NewArrayInit()方法。

也就是说,如果您只需要两个参数(或一个或三个),则可以直接从表达式中使用string.Format()的重载。

params只是语法糖。最终,参数只是一个数组。因此,参数类型应该是object[],并且描述这样一个数组的表达式应该作为第二个参数传递。换句话说,您应该只有两个参数,而不是三个。第二个参数应该是一个包含当前第二个和第三个参数的双元素数组。