Динамически построить фильтр LINQ для метода Any()?
Любой () принимает Func, как я могу динамически создавать фильтры для него? то есть:
var filter = () a=> a.Text == "ok";//add the first filter
if (flag)
filter += () a=> a.ID == 5;//add the second filter << obviously this doesn't work.
list.Any(filter);
Я также видел код для объединения списка Expression>, но я не получаю это, потому что я не знаю, как преобразовать его в Func
Любая помощь будет принята с благодарностью.
3 ответа
Решение
Вы можете создавать фильтры, вызывая другие фильтры из текущего, например:
var input = new[] {"quick", "brown", "fox", "jumps"};
Func<string,bool> filter1 = a => a == "quick";
Func<string,bool> filter2 = a => filter1(a) || a.Length == 3;
foreach (var s in input.Where(filter2)) {
Console.WriteLine(s);
}
Это печатает
quick
fox
Вы можете использовать тот же подход для любых основанных на предикатах функций LINQ, включая Any
:
if (input.Any(filter2)) {
...
}
Вы можете создать IEnumerable<Func<T,bool>>
затем запросить его, например,
Func<int,bool> isGreaterThanEight = x => x > 8;
Func<int,bool> isEven = x => x % 2 == 0;
Func<int,bool> hasFactorFive = x => x % 5 == 0;
IEnumerable<Func<int,bool>> rules = new List<Func<int,bool>>()
{ isGreaterThanEight, isEven, hasFactorFive };
var nums = Enumerable.Range(1,10);
var actual = nums.Where( x => rules.Any( r => r(x) ) );
Assert.That( actual, Is.EqualTo( new[]{2,4,5,6,8,9,10} ) );
Вы можете добавить несколько фильтров в Any
как это.
list.Any(a=>a.Text == "ok" && a.ID == 5);