尝试在foreach循环中将对象附加到Enumerable

时间:2018-08-03 13:45:51

标签: c# foreach append iteration

我正在执行C#练习来创建一个操作,该操作接受一个集合,对该集合中的每个对象执行一个功能,然后返回修改后的对象的集合。

我的代码当前如下:

public static IEnumerable<U> Accumulate<T, U>(this IEnumerable<T> collection, Func<T, U> func)
{
    IEnumerable<U> output = Enumerable.Empty<U>();

    foreach (T item in collection)
    {
        output.Append(func(item));
    }

    return output;
}

这只是返回一个空集合,我不知道为什么。

在另一个线程中看到这种方法后,我尝试在foreach中创建项目的副本,如下所示:

foreach (T item in collection)
    {
        U copy = func(item);
        output.Append(copy);
    }

但这并不能解决任何问题。

我做了一些研究,但实际上找不到任何示例完全符合我在此尝试做的事情。我读了一些有关闭包的内容,但由于我是C#的新手,所以无法真正理解。

2 个答案:

答案 0 :(得分:10)

要回答您的实际问题:不起作用的原因是因为

output.Append(func(item));

不更改output-而是返回一个新序列,该序列附加到func(item)的{​​{1}}上。因此,当您最终返回output时,您只是在返回原始的空序列。

您可以通过以下简单的更改使您的工作正常:

output

但是,这不是一种有效的方法-使用yield会更好,方法如下:

output = output.Append(func(item));

尽管请注意,它更简单地表示为:

public static IEnumerable<U> Accumulate<T, U>(this IEnumerable<T> collection, Func<T, U> func)
{
    foreach (T item in collection)
    {
        yield return func(item);
    }
}

但是了解如何使用public static IEnumerable<U> Accumulate<T, U>(this IEnumerable<T> collection, Func<T, U> func) { return collection.Select(item => func(item)); } 来执行此操作很有用,这样您就可以为更复杂的类似Linq的问题编写解决方案。

答案 1 :(得分:2)

通常,当我想实现这种行为时,我会使用C#迭代器。 当您要处理某种类型的数据的迭代时,它们非常有用,并且在每次迭代时,返回一个附加到结果集合中的值。

看看文档:{​​{3}}