假设我有IEnumerable<Func<object, bool>>
。我想创建一个新的Func<object, bool>
,如果该列表的每个函数在某个对象上调用时返回true,则返回true。换句话说,我想聚合(reduce \ foldl)一个函数列表。
答案 0 :(得分:5)
这样做:
Func<object, bool> aggregate = o => functions.All(f => f(o));
当然这是作弊,因为函数碰巧返回bool
,所以我们可以直接使用Enumerable.All
来产生聚合结果。这也有副作用,即不会调用列表中的所有函数 - 只要一个人返回false
,我们就会打包并离开。
在一般情况下,这种处理是使用Enumerable.Aggregate
完成的,可以这样:
Func<object, bool> aggregate = o =>
functions.Select(f => f(o))
.Aggregate(true, (result, @partial) => result && @partial);
答案 1 :(得分:1)
Jon指出,最好的方法是使用Enumerable.All
。但是,您可以使用Aggregate
折叠序列,这样您也可以这样做:
Func<object, bool> folded = funcs.Aggregate((acc, f) => new Func<object, bool>(o => acc(o) && f(o)));
此重载要求序列非空,但您可以为累加器提供初始值:
Func<object, bool> folded = funcs.Aggregate(new Func<object, bool>(_ => true), (acc, f) => (o => acc(o) && f(o)));
答案 2 :(得分:0)
我会这样做:
bool evaluateAllFuncs(object someObject)
{
IEnumerable<Func<object, bool>> funcs = GetAllFuncs();
return funcs.All(f => f(someObject)));
}