Метод расширения с помощью лямбда / селектора / предиката - PullRequest
0 голосов
/ 11 июня 2011

Я пытаюсь поместить следующую логику в метод 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 / selection, чтобы фактически выполнить работу, которую я хочу сделать:

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

Ответы [ 2 ]

1 голос
/ 11 июня 2011
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.

0 голосов
/ 11 июня 2011

Посмотрите на библиотеку Dynamic LINQ , если вы действительно хотите использовать string запросы.

Если вы в порядке с лямбдами, просто используйте разные предикаты:

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

Это не будет работать для баз данных.

...