只是想更好地理解这一点。我知道这是因为延迟执行
但是是什么导致该方法没有立即被调用。这是来自 JonSkeet 的 EduLinq。
public static partial class Enumerable
{
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;
}
}
}
}
这就是我正在使用它的地方。
List<int> list = new List<int>() { 1, 3, 4, 2, 8, 1 };
var s = list.Where(x => x > 4);
var result = s.ToList();
我的问题是Where
是 IEnumerable 上的静态方法,为什么不在 list.where() 上调用它。但它是在 s.ToList() 上调用的。
我在 Enumerable.Where() 上有一个断点,但没有命中s = list.Where(x => x > 4)
但断点被击中s.ToList()
当我看到评论后YUCK
Why does LINQ have deferred execution?
我将其添加到问题中。
请告诉我。
The Where
方法实际上被调用了,但它返回一个IEnumerable<T>
。这个返回值实际上是编译器为你实现的一个类。
请注意,您的实现使用iterator(它包括收益率......)。发生这种情况时,编译器会更改您的方法,以便创建编译器生成的类,并且,当你实际迭代时通过IEnumerable<T>
,您编写的代码将被执行。
第一次MoveNext
被调用,直到你的第一个代码yield return
将被处决。第二次调用将持续到下一次调用,依此类推。
Calling ToList()
枚举整个IEnumerable<T>
,它又执行您的整个方法。
Also - ToList()
此处不需要执行您的代码。您可以使用 foreach 循环:
foreach(var val in s)
{
// Do something...
}
或者甚至手动执行调用:
IEnumerable<int> s = list.Where(x => x > 4);
IEnumerator<int> sEnumerator = s.GetEnumerator(); // Get the enumerator
// This section will cause your code to run, but only until the *first* yield statement...
if (sEnumerator.MoveNext())
{
int val = sEnumerator.Current();
}
// Without further MoveNext() calls, you won't "finish" the foreach loop...
// This block will do one more "loop" in your foreach, going until the next "yield" (or the end of the method)
if (sEnumerator.MoveNext())
{
int val = sEnumerator.Current();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)