c# – 为什么Linq扩展方法不是坐在IEnumerator而不是IEnumerable?

前端之家收集整理的这篇文章主要介绍了c# – 为什么Linq扩展方法不是坐在IEnumerator而不是IEnumerable?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
有很多 Linq算法只需要一次通过输入,例如选择.

然而,所有的Linq扩展方法都位于IEnumerable而不是IEnumerator

var e = new[] { 1,2,3,4,5 }.GetEnumerator(); 
    e.Select(x => x * x); // Doesn't work

这意味着你不能在任何从“已经打开的”流中读取的情况下使用Linq.

这个方案正在为我目前正在开发的项目发生很多事情 – 我想返回一个IEnumerator,其IDispose方法关闭流,并且所有下游的Linq代码都可以在此操作.

简而言之,我有一个“已经打开”的结果流,我可以将其转换成适当的一次性IEnumerator – 但不幸的是,所有下游代码都需要一个IEnumerable而不是IEnumerator,尽管它只会执行一个“pass”.

即我想要在各种不同的来源(CSV文件,IDataReaders等)上“实现”这种返回类型:

class TabularStream 
{ 
    Column[] Columns; 
    IEnumerator<object[]> RowStream; 
}

为了获得“列”,我必须已经打开了CSV文件,启动了SQL查询,或者其他.然后我可以返回其“Dispose”方法关闭资源的“IEnumerator”,但是所有Linq操作都需要一个IEnumerable.

我知道的最好的解决方法是实现一个IEnumerable,其GetEnumerator()方法返回一个唯一的IEnumerator,如果有人尝试执行一次GetEnumerator()调用两次,则会抛出一个错误.

这一切听起来还是有一个更好的方法来实现“TabularStream”的一个方便从Linq使用的方式?

解决方法

使用IEnumerator< T>在我看来,直接很少是个好主意.

一方面,它编码了它是破坏性的事实 – 而LINQ查询通常可以多次运行.它们意味着是无副作用的,而迭代在IEnumerator< T>自然是副作用的.

这也使得实际上不可能在LINQ to Objects中执行一些优化,例如如果您实际上要求ICollection< T>使用Count属性,为它的数量.

对于您的解决方法:是的,OneShotEnumerable将是一个合理的方法.

猜你在找的C#相关文章