Chiamare il metodo statico in expression.call con argomenti

.net c# delegates expression-trees lambda

Domanda

Ho esteso la classe della stringa per il metodo Contains . Sto cercando di chiamarlo in Expression.Call , ma come passare correttamente l'argomento?

Codice: String Contiene il metodo:

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

In espressione chiamata come:

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

Errore:

Un'eccezione non gestita di tipo 'System.ArgumentException' si è verificata in System.Core.dll.Informazioni aggiuntive: il metodo statico richiede un'istanza null, il metodo non statico richiede un'istanza diversa da null.

Come chiamare il parametro in miContain per i seguenti metodi Call() ?

Ho aggiornato il codice.

Risposta accettata

Non stai specificando tutti i parametri. Se crei espressioni per tutti, funziona:

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

Risposta popolare

Non hai specificato argomenti sufficienti (2 contro 3). NewContains ha tre argomenti.

Inoltre, poiché questo metodo non è un metodo di istanza, non è possibile impostare questo parametro. Questo sovraccarico sembra migliore.

Probabilmente dovresti aver esaminato la lista dei sovraccarichi . È così che ho trovato la risposta giusta a questa domanda senza conoscerla prima.



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché