Lambda / Selector / Predicate逻辑的扩展方法

时间:2011-06-10 22:46:19

标签: c#-4.0 lambda extension-methods

我正在尝试将以下逻辑放入一个Extension方法中,让我传入Func作为字段的选择器。

public class MyClass {
    public decimal someValue {get; set;}
}

public class NumericSearch {
    decimal searchValue {get; set;}

    // Will be =, <=, >=, >, <
    string searchType {get; set;} 
}

... 

List<MyObject> listOfClass = { ... };

if (search.searchType == "=") {
    listOfClass = listOfClass.Where(l=>l.someValue == 123).ToList();
} else if (search.searchType == "<=") {
    listOfClass = listOfClass.where(l=>l.someValue <= 123).ToList();
} else if (...){
    ...
}

我的目标是能够像这样调用它:

var filteredList = listOfClass.applyNumericSearch(l=>l.someValue, new NumericSearch() { searchValue = 123, searchType = "<="} );

到目前为止,我的方法签名看起来像这样,但我不确定如何处理Lamda /选择部分来实际完成我想要完成的工作:

public static IEnumerable<TSource> applyNumericSearch<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal> selector, NumericSearch search) {

2 个答案:

答案 0 :(得分:1)

public static IEnumerable<TSource> applyNumericSearch<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, decimal> selector,
    NumericSearch search
) {
    var projection = source.Select(x => selector(x));
    if(search.searchType == "<=") {
        return projection.Where(y => y <= search.searchValue);
    }
    // etc.
}

此外,我强烈考虑将searchType作为枚举的实例

public enum SearchType {
    LessThan,
    LessThanOrEqual,
    Equal,
    GreaterThan,
    GreaterThanOrEqual,
    NotEqual
 };

而不是使用string

答案 1 :(得分:0)

如果您真的想使用字符串查询,请查看Dynamic LINQ库。

如果你对lambdas很好,只需使用不同的谓词:

Func<decimal, bool> BuildPredicate (NumericSearch search)
{
    switch (search.Kind) {
        case SearchKind.Equal:
            return (x => x == search.Value);
        case SearchKind.LessThan:
            return (x => x < search.Value);
        // ...
    }
}

// in ApplyNumericSearch
var predicate = BuildPredicate (search);
return source.Where (x => predicate (selector (x));

但这对数据库不起作用。