C# - 对IEnumerable <T>的操作

Mil*_*čka 4 c# ienumerable extension-methods delegates

我已经实现了这个扩展方法:

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

当我做

output.DoForEach<string>(c => Console.WriteLine(c));
Run Code Online (Sandbox Code Playgroud)

没有写入控制台.任何想法为什么这不起作用?谢谢

Ily*_*nov 8

yield return使您查询延迟,换句话说,只有在开始迭代元素时才执行方法.如果延迟时尚,则执行大量LINQ运算符.下一代码演示了此问题

new[] {1,2}.DoForEach(Console.WriteLine).ToList();
Run Code Online (Sandbox Code Playgroud)

打印:

1
2
Run Code Online (Sandbox Code Playgroud)

new[] {1,2}.DoForEach(Console.WriteLine);
Run Code Online (Sandbox Code Playgroud)

没有打印

给出完整的示例,检查下一个片段:

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

foreach (var item in items)
{
    Console.WriteLine ("inside loop:" + item);
}
Run Code Online (Sandbox Code Playgroud)

这将打印

inside query:1
inside loop:1
inside query:2
inside loop:2
Run Code Online (Sandbox Code Playgroud)

它将在第foreach一次迭代时开始打印.构造查询时不会打印任何元素


Gje*_*ema 6

这是因为你正在返回一个迭代器,但却没有执行它.根据你所写的内容,你想要在列表上执行一个动作,而不是从中获取一个枚举器,所以看起来你需要让DoForEach()函数返回void,并且去除yield返回它.这应该将您的输出写入控制台.

编辑:这是一个显示我的意思的片段:

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