![](/img/trans.png)
[英]c# How does Enumerable.SelectMany with two function arguments, produce a combined enumerable?
[英]Rx: EnumerableEx.For() vs Enumerable.SelectMany()
System.Interactive.dll包含一个For()
方法,具有以下实现:
IEnumerable<TResult> For<TSource, TResult>(
IEnumerable<TSource> source,
Func<TSource, IEnumerable<TResult>> resultSelector)
{
return source.Select<TSource, IEnumerable<TResult>>(resultSelector).Concat<TResult>();
}
我错过了什么或者这相当于现有的Enumerable.SelectMany()
,减去this
?
IEnumerable<TResult> SelectMany<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, IEnumerable<TResult>> selector)
好问题。 它们产生相同的结果,但内部实现完全不同。
EnumerableEx.For将被添加到System.Interactive中以维持IObservable和IEnumerables之间的二元性。 请注意,Observable.For和Observable.SelectMany是不同的:
IObservable<TResult> For<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, IObservable<TResult>> resultSelector)
对,
IObservable<TResult> SelectMany<TSource, TResult>(this IObservable<TSource> source, Func<TSource, IObservable<TResult>> selector)
因此,您希望EnumerableEx.For具有此签名,而不是它实际拥有的签名:
IEnumerable<TResult> For<TSource, TResult>(**IObservable**<TSource> source, Func<TSource, IEnumerable<TResult>> resultSelector)
但是,它显然不需要IObservable源。 也许它的意思是。 我会在Rx论坛上问你的问题,看看Rx团队是否有答案。
它们看起来像我的等效功能。 SelectMany是IEnumerable上的扩展方法,而.For在EnumerableEx上作为静态方法编写,因此它们的调用方式不同。
foreach(var s in list.SelectMany(Filter))
{
// ...
}
foreach (var s in EnumerableEx.For(list, Filter))
{
// ...
}
我确定使用每一个都有特定的原因。
我的猜测是SelectMany动态遍历所有内容,而Concat(在For中)遍历所有外部IEnumerable元素,然后开始注册并迭代它们。
换句话说,Concat使用一组固定的IEnumerable,即使它将它们作为IEnumerable接收它们。 因此,在For中,甚至在返回第一个TResult之前创建了整个IEnumerable集。 在SelectMany中,您会立即收到一个TResult。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.