我正在阅读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
方法返回,并在...内部返回
SkipWhileIterator
,CLR
遍历原始列表之一
一个并在每个项目上执行谓词。如果
谓词返回false,然后SkipWhileIterator
返回该值
作为SkipWhile
方法的结果的项目;或者如果它返回true,
然后它继续通过列表直到它完成。
到目前为止,一切正常。
但是,我观察了this web site的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
的值必须设置为false ,否则如果值为True,它将不会进入第一个if语句。
感谢。
答案 0 :(得分:1)
一旦SkipWhile
找到与谓词不匹配的值,它就会停止查看并返回序列的其余部分。 yielding
开始为false,因此不会返回元素,并且在第一个不匹配时,它将设置为true。在那之后,它不会想要再次进入第一个if
语句,因为它已经知道它将在那之后返回元素。
答案 1 :(得分:1)
我认为你需要阅读方法文档来理解逻辑:
只要指定条件为真,序列中的元素就会跳转,则返回其余元素。
yielding
未再次设置为false
,因为这是所需的行为。谓词只应匹配一次