Call Static Method in expression.call with arguments

.net c# delegates expression-trees lambda

Question

I have extended the string class for Contains method. I'm trying to call it in Expression.Call, but how to pass the argument properly?

Code: String Contains method:

public static class StringExts
{
    public static bool NewContains(this string source, string ValToCheck, StringComparison StrComp)
    {
        return source.IndexOf(ValToCheck, StrComp) >= 0;
    }
}

In Expression calling as :

public class Person { public string Name {get; set;} }

public class Persons { 
    public List<Person> lstPersons {get; set;} 
    public Persons() {
      lstPersons = new List<Person>();    
    }
}

public class Filter 
{
    public string Id { get; set; }
    public Operator Operator { get; set; }
    public string value { get; set; }
}

public void Main()
{
   //Get the json.
   //"Filters": [{"id": "Name", "operator": "contains", "value": "Microsoft"}]

    Filter Rules = JsonConvert.DeserializeObject<Filter>(json);

   // Get the list of person firstname.
    List<Person> lstPerson = GetFirstName();

   ParameterExpression param = Expression.Parameter(typeof(Person), "p");
   Expression exp = null;

   exp = GetExpression(param, rules[0]);

   //get all the name contains "john" or "John"
   var filteredCollection = lstPerson.Where(exp).ToList();

}

private Expression GetExpression(ParameterExpression param, Filter filter){
   MemberExpression member = Expression.Property(param, filter.Id);
   ConstantExpression constant = Expression.Constant(filter.value);

   Expression bEXP = null;

   switch (filter.Operator)
    {
         case Operator.contains:
           MethodInfo miContain = typeof(StringExts).GetMethod("NewContains", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
           return  Expression.Call(miContain, member, constant , Expression.Constant(StringComparison.OrdinalIgnoreCase));; 
           break;
    }
 }

Error:

An unhandled exception of type 'System.ArgumentException' occurred in System.Core.dll.Additional information: Static method requires null instance, non-static method requires non-null instance.

How to call the parameter in miContain for following Call() methods?

I have updated the Code.

1
9
8/10/2015 12:10:18 PM

Accepted Answer

You are not specifying all parameters. If you create expressions for all, it works:

ParameterExpression source = Expression.Parameter(typeof(string));
string ValToCheck = "A";
StringComparison StrComp = StringComparison.CurrentCultureIgnoreCase;

MethodInfo miContain = typeof(StringExts).GetMethod("NewContains", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
var bEXP = Expression.Call(miContain, source, Expression.Constant(ValToCheck), Expression.Constant(StrComp));

var lambda = Expression.Lambda<Func<string, bool>>(bEXP, source);

bool b = lambda.Compile().Invoke("a");
13
8/10/2015 11:38:03 AM

Popular Answer

You haven't specified enough arguments (2 vs. 3). NewContains has three arguments.

Also, since this method is not an instance method you can't set the this parameter. This overload looks better.

You probably should have examined the overload list. That is how I found the right answer to this question without knowing it myself beforehand.



Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow