理解SkipWhileIterator方法的实现

本文关键字:实现 方法 SkipWhileIterator 理解 | 更新日期: 2023-09-27 18:14:57

我正在阅读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在SkipWhileIterator上执行ToList方法从SkipWhile方法返回,并在SkipWhileIterator, CLR循环遍历原来的list并对每个项执行谓词。如果谓词返回false,则SkipWhileIterator返回该值item作为SkipWhile方法的结果;或者如果它返回true,然后继续遍历列表,直到完成。

到目前为止,一切正常。

但是,然后我从这个网站上观看了SkipWhileIterator的实现。

 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的值必须在第二个if语句中设置为false,否则如果该值为True则无法进入第一个if语句。

谢谢。

理解SkipWhileIterator方法的实现

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

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

From Enumerable.SkipWhile:

绕过序列中的元素,只要指定的条件为真,然后返回剩余的元素。

yielding不再设置为false,因为这是期望的行为。谓词应该只匹配一次