在这段代码中是否真的有多次IEnumerable迭代?

时间:2017-05-18 12:04:03

标签: c# linq ienumerable

    public static IEnumerable<T> ForEach<T>(this IEnumerable<T> source, Action<T> action)
    {
        foreach (var element in source) action(element);
        return source;
    }

上面的代码告诉我一个源可能会多次迭代,但它真的是吗?它在foreach语句中迭代了一次,但是return语句如何让它再次迭代?

2 个答案:

答案 0 :(得分:4)

返回不会再次迭代可枚举。但是你正在返回它,并且因为你可以用这个结果做任何事情的唯一方法是在其他地方迭代它,这个警告是给出的。

为什么要在以后不再进行迭代时返回它?

答案 1 :(得分:1)

在当前代码中,您显示只有一次迭代。由于返回了相同的可枚举,因此很有可能在其他地方再次枚举它。这就是警告告诉你的。

我个人的偏好是将ForEach的返回类型更改为void,然后添加第二个返回Func<T, R>的结果。

所以:

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
    foreach (var element in source)
        action(element);
}

public static IEnumerable<R> ForEach<T, R>(this IEnumerable<T> source, Func<T, R> action)
{
    foreach (var element in source)
        yield return action(element);
}

这样你就不会意外地重复使用相同的可枚举,而是让它变得懒惰:它在你实际调用可枚举之前不会执行。