是否可以创建一个自定义lambda函数,我可以用下面的.Contains()/.StartsWith()/EndsWith()
调用替换它?
如果是这样,我不必在此处比较search
字符串,但我可以在此自定义函数中执行此操作。如果我是对的,这将删除下面的2/3代码。
...或者如果您对如何最大限度地减少这种情况有任何其他想法,我很高兴听到它!
private void searcher(ref Expression<Func<Party, bool>> predicate, string search, string keyword, string column)
{
if (search == "contain")
{
if (column == "surname") predicate = predicate.And(p => p.surname.Contains(keyword));
if (column == "lastname") predicate = predicate.And(p => p.lastname.Contains(keyword));
if (column == "comment") predicate = predicate.And(p => p.comment.Contains(keyword));
if (column == "position") predicate = predicate.And(p => p.position.Contains(keyword));
}
else if (search == "start")
{
if (column == "surname") predicate = predicate.And(p => p.surname.StartsWith(keyword));
if (column == "lastname") predicate = predicate.And(p => p.lastname.StartsWith(keyword));
if (column == "comment") predicate = predicate.And(p => p.comment.StartsWith(keyword));
if (column == "position") predicate = predicate.And(p => p.position.StartsWith(keyword));
}
else if (search == "end")
{
if (column == "surname") predicate = predicate.And(p => p.surname.EndsWith(keyword));
if (column == "lastname") predicate = predicate.And(p => p.lastname.EndsWith(keyword));
if (column == "comment") predicate = predicate.And(p => p.comment.EndsWith(keyword));
if (column == "position") predicate = predicate.And(p => p.position.EndsWith(keyword));
}
}
答案 0 :(得分:2)
可能会想要为字符串编写扩展名(注意,对于where
的枚举,这样会更好):
public static bool Exists(this string str, string where, string what)
{
if(where == "start") return str.StartsWith(what);
if(where == "end") return str.EndsWith(what);
if(where == "contain") return str.Contains(what);
return false;
}
然后你的代码变得更简单了:
private void searcher(ref Expression<Func<Party, bool>> predicate, string search, string keyword, string column)
{
if (column == "surname") predicate = predicate.And(p => p.surname.Exists(search ,keyword));
if (column == "lastname") predicate = predicate.And(p => p.lastname.Exists(search ,keyword));
if (column == "comment") predicate = predicate.And(p => p.comment.Exists(search ,keyword));
if (column == "position") predicate = predicate.And(p => p.position.Exists(search ,keyword));
}
答案 1 :(得分:1)
您可以将search
替换为第二个代表,如下所示:
private void searcher(ref Expression<Func<Party, bool>> predicate, Func<string, string, bool> searchPredicate, string keyword, string column)
{
if (column == "surname") predicate = predicate.And(p => searchPredicate(p.surname, keyword));
if (column == "lastname") predicate = predicate.And(p => searchPredicate(p.lastname, keyword));
if (column == "comment") predicate = predicate.And(p => searchPredicate(p.comment, keyword));
if (column == "position") predicate = predicate.And(p => searchPredicate(p.position, keyword));
}
然后你可以自由地传入从字符串调用字符串并返回bool的任何委托:
searcher(yourFirstPredicate, (s, k) => s.Contains(k), column);
或如果你真的想使用这个词作为搜索委托的关键字,你可以定义一个方法来返回你的委托:
private static Func<string, string, bool> searchSwitcher(string searchType)
{
switch(searchType)
{
case "end":
return (s, k) => s.EndsWith(k);
case "start":
return (s, k) => s.StartsWith(k);
default:
return (s, k) => s.Contains(k);
}
}
然后将您的searcher()方法更改为:
private void searcher(ref Expression<Func<Party, bool>> predicate, string search, string keyword, string column)
{
var searchDelegate = searchSwitcher(search);
if (column == "surname") predicate = predicate.And(p => searchDelegate(p.surname, keyword));
if (column == "lastname") predicate = predicate.And(p => searchDelegate(p.lastname, keyword));
if (column == "comment") predicate = predicate.And(p => searchDelegate(p.comment, keyword));
if (column == "position") predicate = predicate.And(p => searchDelegate(p.position, keyword));
}
答案 2 :(得分:1)
这是使用反射和表达式树的通用方法中的解决方案。你需要的可能有点过分,但它给了我借口表达树的借口。
private bool Searcher<T>(T obj, string search, string keyword, string column)
{
PropertyInfo property = obj.GetType().GetProperty(column);
Dictionary<string, string> dict = new Dictionary<string, string>() { { "contain", "Contains" }, { "start", "StartsWith" }, { "end", "EndsWith" } };
if (property != null && dict.ContainsKey(search) )
{
ParameterExpression objExpression = Expression.Parameter(typeof(T), "obj");
MemberExpression prop = Expression.Property(objExpression, property);
MethodCallExpression startsWith = Expression.Call(prop, typeof(String).GetMethod(dict[search], new Type[] { typeof(String) }), Expression.Constant(keyword));
Expression<Func<T, bool>> expression = Expression.Lambda<Func<T, bool>>(startsWith, objExpression);
var func = expression.Compile();
return func(obj);
}
else
return false;
}