2011-08-23 36 views
2

是否可以創建一個自定義lambda函數,我可以用下面的.Contains()/.StartsWith()/EndsWith()調用替換掉?自定義函數來替換lambdas 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

你也可以用第二個委託代替「搜索」... –

回答

1

也許會寫字符串的擴展(請注意,這將是更好還是與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)); 
} 
+0

我覺得我更喜歡這個......可能是因爲我理解它更好= / – Niklas

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

然後,你可以自由地從一個字符串調用一個字符串,並返回布爾任何代表經過:

searcher(yourFirstPredicate, (s, k) => s.Contains(k), column); 

如果你真的想用這個詞作爲搜索委託的關鍵字,你可以定義一個方法來返回你的d elegate:

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

那麼你的搜索()方法更改爲:

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

下面是使用反射和表達式樹的通用方法中的解決方案。可能是爲了你需要的矯枉過正,但它給了我一個藉口來表達樹的問題。

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; 
    } 
相關問題