尝试在 foreach 循环中将对象附加到 Enumerable
Posted
技术标签:
【中文标题】尝试在 foreach 循环中将对象附加到 Enumerable【英文标题】:Trying to append objects to an Enumerable in a foreach loop 【发布时间】:2019-01-11 10:23:56 【问题描述】:我正在做一个 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# 的新手,所以并不能真正理解它。
【问题讨论】:
请注意,这也可以在 Linq 中实现:var output = collection.Select(x => SomeFunction(x));
追加不会修改你的收藏,它返回一个新的。顺便说一句,这适用于所有 LINQ 方法。
或更多缩写:var output = collection.Select(SomeFunction);
补充@HimBromBeere 所说的内容,如果您检查the docs,您可以看到Append()
返回具有最新附件的IEnumerable
@maccettura 是的,我明白了 :)
【参考方案1】:
回答您的实际问题:它不起作用的原因是因为
output.Append(func(item));
不会改变output
- 相反,它会返回一个新序列,即func(item)
附加到output
。因此,当您最终返回 output
时,您只是返回了原始的空序列。
你可以通过这个简单的改变来使你的工作:
output = output.Append(func(item));
但是,这不是一种有效的方法 - 你最好使用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);
虽然请注意,这更简单地表示为:
public static IEnumerable<U> Accumulate<T, U>(this IEnumerable<T> collection, Func<T, U> func)
return collection.Select(item => func(item));
但了解如何使用 yield
执行此操作很有用,这样您就可以为更复杂的类似 Linq 的问题编写解决方案。
【讨论】:
谢谢你,我不知道正确使用产量。【参考方案2】:通常,当我想实现这种行为时,我会使用 C# 迭代器。 当您想要处理某种数据的迭代并在每次迭代时返回一个附加到结果集合的值时,它们非常有用。
查看文档:MS Docs
【讨论】:
按喜好链接 inglese solo Fixato, chiedo scusa 非全神贯注以上是关于尝试在 foreach 循环中将对象附加到 Enumerable的主要内容,如果未能解决你的问题,请参考以下文章