2015-08-10 16 views
6

Tôi đã mở rộng lớp chuỗi cho phương thức Contains. Tôi đang cố gắng gọi nó trong Expression.Call, nhưng làm thế nào để vượt qua đối số đúng cách?Gọi Phương thức tĩnh trong expression.call với đối số

Mã: String Có phương pháp:

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

Trong biểu thức gọi là:

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

Lỗi:

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.

Làm thế nào để gọi các tham số trong miContain cho sau Call() phương pháp?

Tôi đã cập nhật Mã.

+1

Hơi tắt chủ đề nhưng bạn biết rằng đã có ['String.Contains'] (https://msdn.microsoft.com/en-us/) phương thức library/dy85x1sa (v = vs.110) .aspx)? – Sayse

+0

@Sayse Không có một trong đó có StringComparison như là một đối số bổ sung. –

Trả lời

6

Bạn không chỉ định tất cả thông số. Nếu bạn tạo biểu thức cho tất cả, nó sẽ hoạt động:

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

Cảm ơn bạn đã trả lời. Tôi đang sử dụng Expression trong Linq.Where(), có thể là nguồn thành viên như vậy. Expression.call (miContain, member, Expression.Constant (ValToCheck), Expression.Constant (StrComp) –

+2

Chắc chắn, vượt qua trong một 'ParameterExpression'. Cập nhật câu trả lời của tôi –

+0

Câu trả lời của bạn cũng đã giúp tôi giải quyết vấn đề của mình.Được rồi @PatrickHofman bạn có thể sử dụng ".Where (expressionCompiled)" theo cách tổng quát hơn, đọc bài đăng trên blog này www.pashov.net/code/dynamic+filters –

0

Bạn chưa chỉ định đủ đối số (2 so với 3). NewContains có ba đối số.

Ngoài ra, vì phương pháp này không phải là phương pháp thể hiện, bạn không thể đặt tham số này. This overload looks better.

Có thể bạn đã kiểm tra overload list. Đó là cách tôi tìm ra câu trả lời đúng cho câu hỏi này mà không biết trước.

Các vấn đề liên quan