C# - 对IEnumerable<T>执行操作

5

我实现了这个扩展方法:

public static IEnumerable<T> DoForEach<T>(this IEnumerable<T> data, Action<T> action)
{
    foreach (T value in data)
    {
        action(value);
        yield return value;
    }
}

当我执行

output.DoForEach<string>(c => Console.WriteLine(c));

控制台上没有任何输出。有什么想法为什么不起作用吗?谢谢。

2个回答

8

yield return 使查询变得懒惰,换言之,当您开始迭代元素时,您的方法才会执行。许多LINQ运算符在延迟执行时执行。下面的代码演示了这个问题。

new[] {1,2}.DoForEach(Console.WriteLine).ToList();

输出:

1
2

new[] {1,2}.DoForEach(Console.WriteLine);

不会输出任何内容

为了举例说明,让我们看下面的代码片段:

IEnumerable items = new[] {1,2}.DoForEach(s => Console.WriteLine("inside query:"+s));

foreach (var item in items)
{
    Console.WriteLine ("inside loop:" + item);
}

这将会打印出来

inside query:1
inside loop:1
inside query:2
inside loop:2

只有在第一次 foreach 迭代时才开始打印,当您构建查询时不会打印任何元素。


6

这是因为你返回了一个迭代器,但没有执行它。根据你所写的内容,你想在列表上执行一个操作,而不是从中获取枚举器,因此看起来你需要让DoForEach()函数返回void,并在其中取消yield return。这样应该会将输出写入控制台。

编辑:下面是一个片段,展示了我的意思:

    public static void DoForEach<T>(this IEnumerable<T> data, Action<T> action)
    {
        foreach (T value in data)
        {
            action(value);
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接