Search code examples
c#.netienumerableexpression-trees

Expression.Call with IEnumerable<string> parameter


I want to implement this simple code using expression tree.

var strs = new List<string>(){"m", "k", "l"};
var result = string.Concat(strs); // result = "mkl"

My code looks like:

var exps = new List<Expression>
{ 
   Expression.Constant("m"), 
   Expression.Constant("k"), 
   Expression.Constant("l") 
};
var concat = typeof(string).GetMethod("Concat", new[] { typeof(IEnumerable<string>) });
Expression.Call(concat, exps);

But there is exception: Wrong number of type arguments passed to method

What's wrong and how I can do it?


When I use:

var concat = typeof (string).GetMethod("Concat", new[] {typeof (string), typeof (string)});
Expression.Call(concat, exps[0], exps[1]);

Solution

  • The Concat here takes an argument of IEnumerable<string> rather than three string arguments, so you should use an expression that is of type IEnumerable<string> for the argument e.g.

    var argExpression = Expression.Constant(new List<string>() { "m", "k", "l" });
    
    var concat = typeof(string).GetMethod("Concat", new[] { typeof(IEnumerable<string>) });
    Expression.Call(concat, argExpression);
    

    To construct an IEnumerable<string> from expressions to pass as a single argument then you could construct an array:

    var exps = new List<Expression>
    { 
        Expression.Constant("m"), 
        Expression.Constant("k"), 
        Expression.Constant("l") 
    };
    
    var concat = typeof(string).GetMethod("Concat", new[] { typeof(IEnumerable<string>) });
    var argExpr = Expression.NewArrayInit(typeof(string), exps);
    Expression.Call(concat, argExpr);