当前位置: 首页 > 编程语言 > C#

IEnumerable如何在后台运行分享

时间:2023-04-10 20:09:09 C#

IEnumerable如何在后台运行我正在徘徊在IEnumerable接口更深层次的功能上。基本上,它充当执行中的中间步骤。例如,如果您编写:IEnumerabletemp=newint[]{1,2,3}.Select(x=>2*x);在使用temp做某事之前(例如Listlist=temp.ToList()),将不会计算(枚举)Select函数的结果。然而,让我困惑的是,因为IEnumerable是一个接口,所以不能通过定义实例化。那么,实际项目(在示例中为2*x项目)在哪个集合中?而且,如果我们要编写IEnumerabletemp=Enumerable.Repeat(1,10);,存储1的底层集合(数组、列表等)是什么?我似乎找不到对此接口及其功能的实际实现的详尽(更深入)的解释(例如,如果有底层集合,yield关键字如何工作)。基本上,我要的是对IEnumerable的作用进行更详细的解释。并非所有实现IEnumerable的对象都以某种方式延迟执行。接口的API可以延迟执行,但它不需要它。相同的实现不会以任何方式延迟执行。那么,实际项目(在示例中为2*x项目)在哪个集合中?没有人在那里。每当请求下一个值时,它都会根据需要计算一个值,将其提供给调用者,然后忘记它。它不会将其存储在其他任何地方。而且,如果我们要编写IEnumerabletemp=Enumerable.Repeat(1,10);,存储1的底层集合(数组、列表等)是什么?没有任何。当您要求下一个值时,它会立即计算每个新值并且之后不会记住它。它只存储足以计算下一个值的信息,这意味着它只需要存储元素和剩余的值即可生成。创建延迟枚举并不是特别困难,尽管实际的.NET实现将使用更简洁的方法来创建此类类型。这样做比困难更乏味,即使这是很长的路要走。您只需在迭代器的MoveNext方法中计算下一个值。在你问的例子中,Repeat,这很容易,因为你只需要计算是否有另一个值,而不是它是什么:publicclassRepeater:IEnumerator{privateintcount;私有T元素;publicRepeater(Telement,intcount){this.element=element;this.count=计数;}publicTCurrent{get{返回元素;}}objectIEnumerator.Current{get{returnCurrent;}}publicvoidDispose(){}publicboolMoveNext(){if(count>0){count--;返回真;}否则返回假;}publicvoidReset(){thrownewNotSupportedException();(我省略了一个IEnumerable类型,或者一个创建Enumerable新实例的静态Repeat方法。没有什么特别有趣的地方。)一个更有趣的例子是像Count:publicclassCounter:IEnumerator{privateintremaining;publicCounter(intstart,intcount){Current=start;this.remaining=计数;}publicintCurrent{得到;私有集;}objectIEnumerator.Current{get{returnCurrent;}}publicvoidDispose(){}publicboolMoveNext(){if(remaining>0){remaining--;当前++;返回真;}否则返回假;}publicvoidReset(){thrownewNotSupportedException();}}这里我们不只是统计我们有没有其他的值,而是每次为我们请求一个新的值,下一个值是多少。实施并不重要。所有这些(LINQ)方法都返回IEnumerable,接口成员是您唯一可以访问的,这应该足以使用它们。但如果您真的必须知道,可以在http://sourceof.net上找到实际的实现。但是,对于某些方法,您将无法找到明确的类声明,因为其中一些方法使用yieldreturn,这意味着编译器在编译期间生成了正确的类(带有状态机)。例如Enumerable.Repeat是这样实现的:publicstaticIEnumerableRange(intstart,intcount){longmax=((long)start)+count-1;如果(计数Int32.MaxValue)抛出Error.ArgumentOutOfRange(“计数”);返回范围迭代器(开始,计数);}staticIEnumerableRangeIterator(intstart,intcount){for(inti=0;i您可以在MSDN上阅读更多相关信息:Iterators(C#andVisualBasic)那么,实际项目所在的集合是什么(在示例中2*xitems)是?它不在任何地方。会有代码在迭代时“按需”生成单个项目,但不会预先计算2*x数字。除非你调用ToList或ToArray,否则它们不会存储在任何地方.此外,如果我们要编写IEnumerabletemp=Enumerable.Repeat(1,10);,存储1的底层集合(数组、列表等)是什么?此处相同图片:IEnumerable的返回实现不是公开的,它根据需要返回其项,而不将它们存储在任何地方。C#编译器提供了一种无需定义类即可实现IEnumerable的便捷方法。您只需将方法的返回类型声明为IEnumerable,并使用yieldreturn根据需要提供值以上就是C#学习教程的全部内容:IEnumerable是如何在后台运行的,如果对大家有用还需要了解更多关于C#学习教程,希望大家多多关注——本文是收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: