为什么该方法没有被调用?

2023-12-14

只是想更好地理解这一点。我知道这是因为延迟执行

但是是什么导致该方法没有立即被调用。这是来自 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(使用前将#替换为@)

为什么该方法没有被调用? 的相关文章

随机推荐