我同意 Servy 的回答,但是在 cmets 进行之后,我认为这种方法可能会很有趣:
static class EnumerableExtensions
{
public static IEnumerable<TSource> Fork<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> filter,
Action<TSource> secondary)
{
if (source == null) throw new ArgumentNullException("source");
//...
return ForkImpl(source, filter, secondary);
}
private static IEnumerable<TSource> ForkImpl<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> filter,
Action<TSource> secondary)
{
foreach(var e in source)
if (filter(e))
yield return e;
else
secondary(e);
}
}
可以这样使用:
var ints = new [] { 1,2,3,4,5,6,7,8,9 };
// one possible use of the secondary sequence: accumulation
var acc = new List<int>();
foreach (var i in ints.Fork(x => x % 2 == 0, t => acc.Add(t)))
{
//...
}
// later on we can process the accumulated secondary sequence
process(acc);
这里我们对二级序列进行累积(“假”值),但也可以对二级序列进行实时处理,因此只需枚举一次源。