2015-08-10 8 views
6

Ho esteso la classe di stringa per il metodo Contains. Sto cercando di chiamarlo in Expression.Call, ma come passare correttamente l'argomento?Metodo statico di chiamata in expression.call con argomenti

Codice: String Contiene metodo:

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

In Expression chiamando 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:

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.

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

Ho aggiornato il Codice.

+1

Leggermente off-topic, ma ci sei già a conoscenza è un [ 'String.Contains'] (https://msdn.microsoft.com/en-us/ libreria/dy85x1sa (v = vs.110) .aspx) metodo? – Sayse

+0

@Sayse Non ce n'è uno che prenda StringComparison come argomento aggiuntivo. –

risposta

6

Non si stanno specificando tutti i parametri. Se si creano le 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"); 
+1

Grazie per la risposta. Sto usando Expression in Linq.Where(), può essere membro di appartenenza tale. Expression.call (miContain, membro, Expression.Constant (ValToCheck), Expression.Constant (StrComp) –

+2

Certo, passa in un 'ParameterExpression'. Aggiornato la mia risposta –

+0

Le tue risposte mi hanno anche aiutato a risolvere il mio problema. @PatrickHofman anche tu puoi usare ".Where (expressionCompiled)" in un modo più generico, leggi questo blog post www.pashov.net/code/dynamic+filters –

0

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. This overload looks better.

Probabilmente si dovrebbe aver esaminato il overload list. È così che ho trovato la risposta giusta a questa domanda senza conoscerla prima.