我们先去看看公开的.Net4.0的源程序中IEnumerable、IEnumerable、IEnumerator和IEnumerator这四个接口是如何声明的: 需加微信交流群的,请加小编微信号...get; } void Reset(); } 一、接口IEnumerable实现 1、建一个学生数据结构和一个学生集合类: //student数据结构...我们实现了可枚举的自己的类。...return s; } } IEnumerator IEnumerable.GetEnumerator() {...虽然第二种写法比较投机,充分利用了.NET Framework给的各种泛型集合可枚举的特征。不过我们也自己实现了一个GetEnumerator(),了解了枚举器的工作原理。本章学习目的达成。
IEnumerable是所有可迭代非范型类的基础接口。IEnumerable包括一个方法GetEnumerator方法,方法返回一个IEnumerator。...IEnumerator是所有非范型迭代器的基础接口。foreach语句隐藏了C#迭代器的复杂实现。推荐使用foreach代替直接操作迭代器。 迭代器可以读取集合中的数据,但是不能从底层修改集合。...foreach是一种语法糖,简化了遍历其中的具体实现。...被遍历的类通过实现IEnumerable接口和实现一个IEnumerator枚举器实现遍历功能。...IEnumerable.GetEnumerator() { return (IEnumerator)GetEnumerator(); }
,需要做一次数组元素复制,相对性能比较差,如果是做只读,功能和 Span 相反,那么可以通过遍历的数组下标判断 下面方法可以在项目用,做法很简单,看代码也就知道 using System; using...(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator...} throw new IndexOutOfRangeException(); } } } 这个类如果不算传入的只读列表的原列表的更改...,这个类是线程安全的 可能遇到的坑是传入的只读列表的原列表添加了值,也就是 CombineReadonlyList[n] 执行两遍获取的元素可能不相同 更多有趣的数组定义请看 Sakuno.Base.Collections...(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator
虽然一般不推荐这么设计,但是你可以使用本文所述的方法和代码作为按垃圾回收缓存的缓存池的设计。...---- 设计思路 既然现有 WeakReference 和 ConditionalWeakTable 可以帮助我们实现弱引用,那么我们可以考虑封装这两个类中的任何一个或者两个来帮助我们完成弱引用集合...IEnumerable.GetEnumerator() => throw new NotImplementedException(); } this[]、Count、IsReadOnly、Contains...IEnumerable.GetEnumerator() => throw new NotImplementedException(); } 不过,Add 和 Remove 方法可能我们会考虑留下来...1 2 public IEnumerator GetEnumerator() => throw new NotImplementedException(); IEnumerator IEnumerable.GetEnumerator
System.Span 和 System.ReadOnlySpan。 支持常见泛型集合,例如 System.Collections.Generic.List。... GetEnumerator() => _buffer.AsEnumerable().GetEnumerator(); IEnumerator IEnumerable.GetEnumerator...; } } 首先,需要创建一个包含 Create 方法的类:LineBufferBuilder。...最后,必须将 CollectionBuilderAttribute添加到 LineBuffer 类声明。其中,第一个参数提供生成器类的名称, 第二个特性提供生成器方法的名称。...这样一个自定义的类就可以支持集合表达式了。
在以下示例中,DaysOfTheWeek 类实现 IEnumerable 接口,此操作需要 GetEnumerator 方法。...引用类实例 (theZoo) 的 foreach 语句隐式调用 GetEnumerator 方法。...非泛型实现遵从泛型实现的规则。 本示例使用命名迭代器来支持通过各种方法循环访问同一数据集合。 这些命名迭代器为 TopToBottom 和 BottomToTop 属性,以及 TopN 方法。...若要查看编译器执行的操作,可使用 Ildasm.exe 工具查看为迭代器方法生成的 Microsoft 中间语言代码。 为类或结构创建迭代器时,不必实现整个 IEnumerator 接口。...编译器检测到迭代器时,会自动生成 IEnumerator 或 IEnumerator 接口的 Current、MoveNext 和 Dispose 方法。
我们平常使用的数据结构都是采用可变模式来实现的,那怎么实现一个不可变数据结构呢!... GetEnumerator() { yield break; } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator...stack.IsEmpty; stack = stack.Pop()) yield return stack.Peek(); } IEnumerator IEnumerable.GetEnumerator...Net提供的不可变集合 不可变队列,不可变列表等数据结构如果都自己实现工作量确实有点大。幸好的是Net在4.5版本已经提供了不可变集合的基础类库。...; a1.Push(10); //不正确,a1仍是空值值,push会生成新的栈。
如下面的代码片段所示,我们需要在创建一个PhysicalDirectoryInfo对象时提供这个DirectoryInfo对象,PhysicalDirectoryInfo实现的所有属性的返回值都来源于这个... GetEnumerator(); IEnumerator IEnumerable.GetEnumerator(); } 四、NotFoundDirectoryContents... GetEnumerator() => Enumerable.Empty().GetEnumerator(); IEnumerator IEnumerable.GetEnumerator...这些文件或者目录的变化(创建、修改、重命名和删除等)都会实时地反映到Watch方法返回的IChangeToken上。...PhysicalFileProvider针对物理文件系统变化的监控是通过如下这个PhysicalFilesWatcher对象实现的,其Watch方法内部会直接调用PhysicalFileProvider
通过代码的运行结果,我们可以看到这里返回的结果 yield return 和comment return是分成两边的。先执行完一个然后开始执行另外一个。不干涉。...解析定义类 我们已经大致了解了yield 的用法和它与平常的返回的区别。我们可以继续查看其运行原理。...这样去实现的迭代遍历。同时包含_state字段、用来存储上一次的记录。_current包含当前的值、也通过_initialThreadId获取当前线程id。...我们根据反编译结果来实现一个与yiled相似的类: /// /// 解析yield并定义相似类 /// public sealed...IEnumerable.GetEnumerator() { return GetEnumerator(); } [IteratorStateMachine
在.NET6中微软新增了 TryGetNonEnumeratedCount 方法,让我们可以计算可枚举类型元素的总数。...new Employee(); Console.WriteLine($@"{e.Count()}"); class User : IEnumerable { public IEnumerator... GetEnumerator() { throw new NotImplementedException(); } IEnumerator IEnumerable.GetEnumerator...throw new NotImplementedException(); } } 运行上面的代码会发现e.Count()能够执行,但是u.Count()报错,这是LINQ内部实现造成的...因此建议在代码中始终使用如下方式获取可枚举类型的元素总数: if (!
本例子实现了如何自定义线性节点集合,具体代码如下: using System; using System.Collections; using System.Collections.Generic;... GetEnumerator() { return new LineNodeEnumerator(this.firstLineNode);...} IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator();...,从而形成链接的节点; ②本示例完全由博主原创,转载请注明来处。...示例下载地址:https://pan.baidu.com/s/1eS9UIzS (请使用VS2015打开,如果为其他版本,请将Program.cs中的内容复制到自己创建的控制台程序中)
正文 IEnumerable和IEnumerator,如果不仔细看,是不是都以为它们是同样的一个单词。特别是我们习惯了每天看大量的中文,这种只是很小区别的单词更是容易犯错。...好的,回到今天的主题:IEnumerable和IEnumerator。目前我们知道它俩是不一样的东西了,至少从单词层面(ง •_•)ง。那么在 DotNET 中,它们扮演着怎么样的角色呢?...其实看接口的样貌我们就大概能够理解其中的奥秘了,IEnumerable 提供了可以迭代的能力,而这种能力是通过内部的可迭代对象来实现了,这个对象就是IEnumerator。...来实现一个可迭代的双色球迭代器对象: public class BallEnum : IEnumerator { public Ball[] _ball; int position =...IEnumerator IEnumerable.GetEnumerator() { return (IEnumerator)GetEnumerator(); }
首先我们来说下迭代的目的: 迭代是将自定义类变为自定义类数组,并遍历它 在C#1.0和C#2.0这两个版本中,C#2比C#1多了一个更简洁的迭代方法 C#1.0 1️⃣ 实现迭代的操作流程: 1、定义单个类...接口的实现类(内有GetEnumerator方法)、枚举器类,才能在Main方法实例该类数组遍历它, C#2我们仅写单个类、IEnumerable接口的实现类,不必写枚举器类,便可在Main方法实例该类数组并遍历它了...包含GetEnumerator方法和一个可枚举类型的迭代器,该可枚举类型迭代器内部又自动实现了GetEnumerator方法和一个可枚举类型 要想遍历该类a,类a的GetEnumerator方法需获取可枚举类型的...但即使不实现GetEnumerator方法,也能实现枚举 a、实现总类的GetEnumerator方法:迭代器方法ib内自动创建了一个枚举器和一个GetEnumerator方法,如果实现总类的GetEnumerator...再次重申一下,迭代器块可作为方法主体、访问器块主体和运算符主体 5️⃣ 其他注意事项 在编译器生成的IEnumerator枚举器方法中,Reset方法(用来重置)并没有实现,因此调用它会抛出System.NotSpportedception
这样即使多个线程来访问它,它也不会产生对线程来说很意外的数据。 C#中的Dictionary不是线程安全的,我在下面这个例子中,把一个Dictionary对象作为了全局的static变量。...所以我需要包装一下.net自带的Dictionrary. 发生冲突的部分无非是写的地方,所以在离写Dictionary最近的地方加一个锁。其他的外层代码可以自带的Dictionary相同了。...我们看Dictionary的实现接口, 自定义一个线程安全的数据对象类。...IEnumerable.GetEnumerator() { return ((IEnumerable)d).GetEnumerator(); }...).aspx http://www.cnblogs.com/atskyline/p/3234805.html 4.0中新增的线程安全集合类: 线程安全集合类 非线程安全集合类 ConcurrentQueue
一个集合类可以提供多个不同的 GetEnumerator 实现,如 GetEnumerator1,GetEnumerator2,返回不同的 IEnumerator,以实现不同的迭代功能。...(见下文) Part3 IEnumerator 与 yield 一个集合类想要支持被迭代,最主要的是构造一个 Enumerator 类,实现 IEnumerator 接口,在 GetEnumerator...如此,在 Enumerator 类中,需要维护 Current 属性和 MoveNext 方法,在 MoveNext 方法中,更新 Current 的值,并返回是否还有后续值的 bool 判断。...Part4 实现多个不同的 IEnumerator 有一个 MusicCollection 集合类,里面包含了 IList{Music} 集合,现在要在其中实现对 Music.Title , Music.Author...Part5 线程安全 迭代显然是非线程安全的,每次 IEnumerable 都会生成新的 IEnumerator,从而形成多个互相不影响的迭代过程。 在迭代过程中,不能修改迭代集合,否则不安全。
在Main方法中,将GetVetors方法的返回值赋值给一个变量,然后对每一个Vector对象的X和Y进行重新赋值,最后将每一个Vector的信息输出来。...由于两次迭代造作的并不是同一批对象,才会导致X和Y属性依然“保持”着原始的值。... IEnumerable.GetEnumerator(); 13: [DebuggerHidden] 14: IEnumerator IEnumerable.GetEnumerator...{ [DebuggerHidden] get; } 21: } 这是一个实现了众多接口的类型,实现的接口包括:IEnumerable, IEnumerable, IEnumerator...d__0 类大部分成员都没有复杂的逻辑,唯一值得一提的就是MoveNext方法。从中我们清楚地但到,对Vector对象的创建发生在每一个迭代中。
所有当被编译生成成Assembly被CLR加载、执行的时候,CLR是意识不到这些新的特性的。...IEnumerable.GetEnumerator() { throw new Exception("The method or operation is not... _sourceEnumerator; 通过返回一个WhenEnumerator对象,实现了IEnumerable的GetEnumerator()方法。 ...public IEnumerator GetEnumerator() { return new WhenEnumerator(..._predicate); } 对于另一个Interface IEnumerator,直接调用数据源的Enumerator的同名方法实现了Current,和Reset()
实现了这个接口的类可以使用Foreach关键字进行迭代(迭代的意思是对于一个集合,可以逐一取出元素并遍历之)。实现这个接口必须实现方法GetEnumerator。...实现方法GetEnumerator GetEnumerator方法需要一个IEnumerator类型的返回值,这个类型是一个接口,所以我们不能这样写: return new IEnumerator();...我们必须再写一个类PeopleEnumerator,它继承这个接口,实现这个接口所有的成员:Current属性,两个方法MoveNext和Reset。...,编译器将会自动实现继承IEnumerator接口的类和上面的三个方法。...迭代显然是非线程安全的,每次IEnumerable都会生成新的IEnumerator,从而形成多个互相不影响的迭代过程。 在迭代时,只能前进不能后退。新的迭代不会记得之前迭代后值的任何变化。
集合要支持foreach则需要实现System.Collections.IEnumerable接口[公开枚举数,该枚举数支持在非泛型集合上进行简单迭代, 也可以不实现该接口,该接口定义了一个方法GetEnumerator...(),返回一个支持IEnumerator接口的对象,IEnumerator的成员如下: 名称 说明 bool MoveNex t方法 将枚举数推进到集合的下一个元素 void Rese t方法 将枚举数设置为其初始位置...foreach遍历,需要写上面一大堆代码[实现两个接口,也可不实现, 但是必须给提供这两个接口中的同名方法],C#2.0引入了yield return[返回每个元素]和yield break[终止迭代]...只需实现一个接口IEnumerable就可以了[或者说有public IEnumerator GetEnumerator()此方法就可]; 像是匿名方法一样,编译器帮我们做了很多[这里编译器帮我们生成了..."实现IEnumerator接口的一个类",通过查看IL代码得知]。
领取专属 10元无门槛券
手把手带您无忧上云