SkipWhileIterator方法实现了解

时间:2014-07-27 06:04:52

标签: c# .net linq iterator clr

我正在阅读CLR执行SkipWhile方法时发生的事情。例如,让我们采取:

IList<string> numbers = new List<string>() 
{ 
"One","Two","Three", "Four","Five"
};
var result = numbers.SkipWhile(number => number.Length == 3);
result.ToList().ForEach(number => Console.WriteLine(number));

CLR将执行以下步骤:

C#编译器使用匿名构造方法<Main>b__1 编译时的方法(number => number.Length == 3)。 CLR 将使用。实例化MulticastDelegate的实例 <Main>b__1方法作为SkipWhile的谓词。 CLR 使用实例化SkipWhileIterator迭代器的实例 原始列表和谓词<Main>b__1。因为 延迟执行,SkipWhileIterator直到执行才会执行 CLR调用ToList或使用ForEach方法进行迭代 通过。 CLR在ToList上执行SkipWhileIterator方法 从SkipWhile方法返回,并在...内部返回 SkipWhileIteratorCLR遍历原始列表之一 一个并在每个项目上执行谓词。如果 谓词返回false,然后SkipWhileIterator返回该值 作为SkipWhile方法的结果的项目;或者如果它返回true, 然后它继续通过列表直到它完成。

到目前为止,一切正常。

但是,我观察了this web siteSkipWhileIterator的实施情况。

 static IEnumerable<TSource> SkipWhileIterator<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate) {
       bool yielding = false;
       foreach (TSource element in source) {
          if (!yielding && !predicate(element)) yielding = true;
          if (yielding) yield return element;
       }
 }

但是,这不是假的吗?在我看来,第二个if语句必须是这样的:

 if (yielding) {yielding=false; yield return element};
如果

Yielding的值必须设置为false ,否则如果值为True,它将不会进入第一个if语句。

感谢。

2 个答案:

答案 0 :(得分:1)

一旦SkipWhile找到与谓词不匹配的值,它就会停止查看并返回序列的其余部分。 yielding开始为false,因此不会返回元素,并且在第一个不匹配时,它将设置为true。在那之后,它不会想要再次进入第一个if语句,因为它已经知道它将在那之后返回元素。

答案 1 :(得分:1)

我认为你需要阅读方法文档来理解逻辑:

来自Enumerable.SkipWhile

  

只要指定条件为真,序列中的元素就会跳转,则返回其余元素。

yielding未再次设置为false,因为这是所需的行为。谓词只应匹配一次