使用参数调用 expression.call 中的静态方法
Call Static Method in expression.call with arguments
我已经为 Contains
方法扩展了字符串 class。我试图在 Expression.Call
中调用它,但如何正确传递参数?
代码:字符串包含方法:
public static class StringExts
{
public static bool NewContains(this string source, string ValToCheck, StringComparison StrComp)
{
return source.IndexOf(ValToCheck, StrComp) >= 0;
}
}
在表达式调用中:
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;
}
}
错误:
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.
下面的Call()
方法如何调用miContain
中的参数?
我已经更新了代码。
您没有指定足够的参数(2 对 3)。 NewContains
有三个参数。
此外,由于此方法不是实例方法,因此您无法设置此参数。 This overload looks better.
您可能应该检查 overload list。这就是我如何在事先不知道的情况下找到这个问题的正确答案。
您没有指定所有参数。如果您为所有人创建表达式,它会起作用:
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");
我已经为 Contains
方法扩展了字符串 class。我试图在 Expression.Call
中调用它,但如何正确传递参数?
代码:字符串包含方法:
public static class StringExts
{
public static bool NewContains(this string source, string ValToCheck, StringComparison StrComp)
{
return source.IndexOf(ValToCheck, StrComp) >= 0;
}
}
在表达式调用中:
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;
}
}
错误:
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.
下面的Call()
方法如何调用miContain
中的参数?
我已经更新了代码。
您没有指定足够的参数(2 对 3)。 NewContains
有三个参数。
此外,由于此方法不是实例方法,因此您无法设置此参数。 This overload looks better.
您可能应该检查 overload list。这就是我如何在事先不知道的情况下找到这个问题的正确答案。
您没有指定所有参数。如果您为所有人创建表达式,它会起作用:
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");