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

Cal*_*kie 4 c# iteration foreach append

我正在做一个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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

foreach (T item in collection)
    {
        U copy = func(item);
        output.Append(copy);
    }
Run Code Online (Sandbox Code Playgroud)

但这并没有解决任何问题.

我做了一些研究,但实际上找不到任何正如我在这里尝试做的那样的例子.我读了一些关于闭包的东西,但是不能真正理解它,因为我是C#的新手.

Mat*_*son 10

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

output.Append(func(item));
Run Code Online (Sandbox Code Playgroud)

不会改变output- 而是返回一个func(item)附加到的新序列output.因此,当你最终返回时,output你只是返回原始的空序列.

你可以通过这个简单的改变让你的工作:

output = output.Append(func(item));
Run Code Online (Sandbox Code Playgroud)

但是,这不是一种有效的方法 - yield通过修改方法,您可以更好地使用它 :

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

虽然注意到这更简单地表达为:

public static IEnumerable<U> Accumulate<T, U>(this IEnumerable<T> collection, Func<T, U> func)
{
    return collection.Select(item => func(item));
}
Run Code Online (Sandbox Code Playgroud)

但了解如何执行此操作非常有用,yield这样您就可以编写更复杂的Linq问题的解决方案.