Llame al método estático en expression.call con argumentos

.net c# delegates expression-trees lambda

Pregunta

He extendido la clase de cadena para el método Contains . Estoy tratando de llamarlo en Expression.Call , pero ¿cómo pasar el argumento correctamente?

Código: Cadena Contiene método:

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

En la expresión llamando como:

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:

Se produjo una excepción no controlada del tipo 'System.ArgumentException' en System.Core.dll.Información adicional: el método estático requiere una instancia nula, el método no estático requiere una instancia no nula.

¿Cómo llamar al parámetro en miContain para los siguientes métodos de Call() ?

He actualizado el Código.

Respuesta aceptada

No estás especificando todos los parámetros. Si creas expresiones para todos, funciona:

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

Respuesta popular

No has especificado suficientes argumentos (2 contra 3). NewContains tiene tres argumentos.

Además, como este método no es un método de instancia, no puede establecer este parámetro. Esta sobrecarga se ve mejor.

Probablemente debería haber examinado la lista de sobrecarga . Así es como encontré la respuesta correcta a esta pregunta sin saberlo de antemano.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow