我正在阅读Jon Skeet 的 Reimplemnting Linq to Objects 系列。在where文章的实现中,我找到了以下片段,但我不明白将原始方法一分为二有什么好处。
原始方法:
// Naive validation - broken!
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (predicate == null)
{
throw new ArgumentNullException("predicate");
}
foreach (TSource item in source)
{
if (predicate(item))
{
yield return item;
}
}
}
重构方法:
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (predicate == null)
{
throw new ArgumentNullException("predicate");
}
return WhereImpl(source, predicate);
}
private static IEnumerable<TSource> WhereImpl<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate)
{
foreach (TSource item in source)
{
if (predicate(item))
{
yield return item;
}
}
}
乔恩说——它是为了急切地验证,然后推迟剩下的部分。但是,我不明白。
有人可以更详细地解释一下,这两个函数之间有什么区别,为什么验证会在一个而不是另一个中急切地执行?
结论/解决方案:
由于我对哪些函数被确定为迭代器生成器缺乏了解,我感到困惑。我假设,它基于像 IEnumerable
<T>
这样的方法的签名。但是,根据答案,现在我明白了,如果一个方法使用yield 语句,它就是一个迭代器生成器。