Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling (params object[]) with Expression[]

I'm trying to call String.Format from with in a Linq.Expression tree. Here's a quick example:

    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);

The issue however is that String.Format has the signature of:

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

and I'm trying to pass in Expression[].

Now I could go through all the trouble of creating an array, populating it with the results of my expressions, but what I really want the result to be, is something like this:

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

How do I go about calling a params function via Linq Expressions?

like image 245
Timothy Baldridge Avatar asked May 24 '11 22:05

Timothy Baldridge


1 Answers

What params actually does is just to specify ParamArrayAttribute for that parameter. The C# compiler understands this, and creates the array behind the scenes.

Expressions don't understand this, so you actually have to create the array by yourself, if you want to call a method with params. This can be also seen by the fact that when you assign a lambda using params-method to an expression, the expression contains the array creation:

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

Here, expressionString will contain this string:

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

To create an expression that creates an array, use the Expression.NewArrayInit() method.

That being said, if you only want two parameters (or one or three), there is an overload of string.Format() that you can use directly from an expression.

like image 177
svick Avatar answered Nov 10 '22 18:11

svick