什么是IEnumerable? IEnumerable及IEnumerable的泛型版本IEnumerableT>是一个接口,它只含有一个方法GetEnumerator。...Enumerable这个静态类型含有很多扩展方法,其扩展的目标是IEnumerableT>。...如何实现一个继承IEnumerable的类型? 实现一个继承IEnumerable的类型等同于实现方法GetEnumerator。...这个类型实际上的作用就相当于Person[]或List,但我们不能使用它们,因为它们已经实现了IEnumerable,故我们构造一个People类,模拟很多人(People是Person...而且会出现一个问题,就是你无法知道集合的大小(IEnumerable没有Count方法,只有IEnumerableT>才有)。
SomeNumbers() { yield return 3; yield return 5; yield return 8; } 迭代器方法或 get 访问器的返回类型可以是...引用类实例 (theZoo) 的 foreach 语句隐式调用 GetEnumerator 方法。...Push 方法将值分配给类型为 T 的数组。 GetEnumerator 方法通过使用 yield return 语句返回数组值。...除了泛型 GetEnumerator 方法,还必须实现非泛型 GetEnumerator 方法。 这是因为从 IEnumerable 继承了 IEnumerableT>。...必须存在从 yield return 语句中的表达式类型到迭代器返回的 IEnumerableT> 类型参数的隐式转换。 在 C# 中,迭代器方法不能有任何 in、ref 或 out 参数。
2、枚举器实现了IEnumerator接口,所以它能做IEnumerator接口定义的所有工作 3、对于有枚举器的类型而言,必须有一个方法来获取它,获取一个对象枚举器的方法是调用对象的GetEnumerator...方法,实现GetEnumerator方法的类型叫做可枚举类型(enumerable),数组是可枚举类型 释义: 所以在此案例中,采用GetEnumerator()方法将获取到的数组的枚举器赋值给定义为枚举器类型的...ie,GetEnumerator()方法获取到的是返回的枚举器的实例 调用方法时MoveNext要在前,Current方法在后。...[DispId(-4)] IEnumerator GetEnumerator(); } } 可枚举类是指实现了IEnumerable接口的类,IEnumearable接口只有一个成员...GetEnumerator方法,它返回对象的枚举器 综合实例 using System; using System.Collections; class ColorEnumerator : IEnumerator
LINQ to Object的数据源总是实现IEnumerableT>(所以不如叫做LINQ to IEnumerableT>),相对的,LINQ to SQL的数据源总是实现IQueryable类型,它集合了许多扩展方法,扩展的目标是IQueryable和IEnumerable。它令IQueryable和IEnumerable一样,拥有强大的查询能力。...AsQueryable方法将IEnumerableT>转换为IQueryableT>。...因为IQueryableT>继承了IEnumerableT>,所以我们一样要实现GetEnumerator方法。...而我们还需要知道目标实体类的类型名称Staff,所以我们的解析方法还需要接受一个泛型T。 另外,由于我们的解析方法很有可能是递归的(因为要解析表达式树),我们的输出还需要用ref加以修饰。
我们先去看看公开的.Net4.0的源程序中IEnumerableT>、IEnumerable、IEnumeratorT>和IEnumerator这四个接口是如何声明的: 需加微信交流群的,请加小编微信号...public interface IEnumerableT> : IEnumerable { new IEnumeratorT> GetEnumerator();...迭代器工作的原理是:先调用MoveNext()方法,然后读取Current得到元素,直到MoveNext返回false。 我们需要3个字段分别放置 元素的位置、元素、元素集。...(好像有装箱的行为) 第三,在MoveNext方法内累加索引,并从元素集中读取元素。然后让索引值超出元素集返回个false值。 最后,在Reset方法内让索引值为-1,不过好像直接抛出错误也成。...二、接口IEnumerableT>实现 如果我们想写一个通用的可foreach的类,用到泛型: class MyCollectionT> { public List<
接口,所以任何集合类对象都有一个GetEnumerator()方法,该方法可以返回一个实现了 IEnumerator接口的对象,这个返回的IEnumerator对象既不是集合类对象,也不是集合的元素类对象...通过这个对象,可以遍历访问集合类对象中的每一个元素对象 如果集合类是用户自定义的集合类,则用户必须实现它的GetEnumerator()方法,否则不能使用循环。...、可排序 缺点:插入时性能不如数组、不是强类型的 2)BitArray 实现了接口:ICollection、IEnumerable 管理位值的压缩数组。...)Queue 实现了接口:ICollection、IEnumerable Queque是队列,先进先出的访问各个元素 可以调用Queque对象的GetEnumerator()方法,得到IEnumerator...方法,得到IEnumerator对象,来遍历堆栈中的各个元素 3.上面提到的几种集合类,他们都是通用的集合类,他们所接受的元素大都是Object类型,当对象放入 了集合之后,都失去了原有的类型信息-即这些通用集合类都不是强类型的
2:迭代器创建可枚举类型 类a包含GetEnumerator方法和一个可枚举类型的迭代器,该可枚举类型迭代器内部又自动实现了GetEnumerator方法和一个可枚举类型 要想遍历该类a,类a的GetEnumerator...方法需获取可枚举类型的GetEnumerator方法,从而获得可枚举类型迭代器内部的枚举器 a、迭代器创建class类型 using System; using System.Collections.Generic...:如果不实现总类的GetEnumerator方法,Main方法直接采用IEnumerable类型的迭代器(内有GetEnumerator方法),那么就不需要总类的GetEnumerator方法了 using...在一个类中产生多个可枚举类型,那么就不能能实现GetEnumerator方法,因为可枚举类型的GetEnumerator方法主体有固定格式,无法再次写个GetEnumerator方法,那样就会重名,且...Main方法调用的也不知是哪个正确的GetEnumerator方法 一个类产生多个可枚举类型,而是采用不实现GetEnumerator的方法,Main方法直接调用返回可枚举类型的迭代器,即上文的“b、不实现
IEnumerable ,因此我们要实现序列中元素的倒叙访问就必须采用 GetEnumerator 种的方式。...首次调用这个方法时会把输入的序列访问一遍,然后让嵌套类可以在这个列表上反向访问元素。...要解决这个问题我们只需要修改一下 DemoEnumerable 的构造函数然后增加一个参数为 IList 类型的构造函数即可: public DemoEnumerable(IEnumerableT>...有时尽管参数实现了 IList 但是它的编译期类型仍然是 IEnumerable,因此我们必须提供新的构造函数的同时修改旧的构造函数。...一、第二次优化 上述代码基本上囊括了大部分情况,但有时我们还会遇到一些集合只实现了 ICollection 而没有实现 IList 的情况,这种情况下我们代码中的 GetEnumerator 方法性能就不是很高了
IEnumerableT>的派生类:小结 访问方式 继承自 特点 IEnumerableT> 通过ElementAt 无 所有泛型集合都继承自此接口 有非泛型版本 提供遍历(通过GetEnumerator...IEnumerableT>替代作为返回类型 IQueryableT> 通过IndexOf IEnumerableT> 从远端获得筛选之后的资料,和IEnumerableT>不同,IQueryable...通常将迭代中拿出来的元素称为iterator。 实现IEnumerable接口,必须实现它唯一的方法GetEnumerator。...方法GetEnumerator返回一个IEnumerator类型的输出。...IEnumerator类型又是一个接口,所以我们还要写一个类,并将这个类继承IEnumerator接口(实现它的2个方法),建立这个类的一个新实例,并传入一个数组(作为迭代的源)作为方法GetEnumerator
如果要实现一个自定义的集合类,最好不要以ListT>作为基类,而应该扩展相应的泛型接口,通常是IenumerableT>和ICollectionT>(或ICollectionT>的子接口,如...建议24、迭代器应该是只读的 前端时间在实现迭代器的时候我就发现了这样一个问题,迭代器中只有GetEnumeratior方法,没有SetEnumerator方法。...这段代码的问题就是:线程t1模拟将对类型StudentTeamA的Students属性进行赋值,它是一个可读/可写的属性。...在例子中,我们将list赋值为null,模拟在StudentTeamA(或者说工作线程t1)不知情的情况下使得集合属性变为null。...接着,线程t1模拟针对Students属性进行若干操作,导致异常的抛出。
会被编译成Nullable类型,即可空类型 public struct NullableT> where T : struct { ... } 下面演示一下使用方法 static void...当把一个可空类型赋给引用变量时,CRL会对可空类型(NullableT>)对象进行装箱处理。...因为foreach就需要一个迭代器,IEnumerable接口中定义了一个GetEnumerator方法用来返回迭代器,类型如果实现了IEnumerable接口,则也必须实现GetEnumerator方法...,因此也就可以使用foreach语句了 在 C# 1.0 中,要获取迭代器,就必须要实现 IEnumerable或GetEnumerator 方法;而要实现一个迭代器,就必须要实现IEnumerable...,GetEnumerator方法不是一个普通方法,而是实现迭代器的方法。
你可以参考我的另一篇博客了解设计这种不确定类型的 API 的时候的一些指导: 如何为非常不确定的行为(如并发)设计安全的 API,使用这些 API 时如何确保安全 总结起来就是: 必须提供一个单一的方法...,能够完成一些典型场景下某一时刻确定性状态的获取 绝不能提供一些可能多次调用获取状态的方法 那么这个原则怎么体现在此弱引用集合的类型设计上呢?...IEnumerableT> IEnumerableT> 里面只有两个方法,看起来少多了,那么我们能用吗?...1 2 public IEnumeratorT> GetEnumerator() => throw new NotImplementedException(); IEnumerator IEnumerable.GetEnumerator...对于并发可以使用锁,但对于弱引用,没有可以使用的相关方法来快速解决问题。 因此,IEnumerableT> 也是不能继承的。 object 看来,我们只能继承自单纯的 object 基类了。
C#12中引入了新的语法糖来创建常见的集合。并且可以使用..来解构集合,将其内联到另一个集合中。 支持的类型 数组类型,例如 int[]。...类型通过编写 Create() 方法,和对集合类型应用System.Runtime.CompilerServices.CollectionBuilderAttribute 选择加入集合表达式支持。...() => _buffer.AsEnumerable().GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => _buffer.GetEnumerator...LineBufferBuilder.Create方法必须返回 LineBuffer 对象,并且必须采用 ReadOnlySpan 类型的单个参数。...其中,第一个参数提供生成器类的名称, 第二个特性提供生成器方法的名称。 这样一个自定义的类就可以支持集合表达式了。
还有就是继承IEnumerableT>对象让我们自己的集合类型具备LINQ的强类型的查询能力。当然具体要看我们需求,从技术角度看目前只有这两点可以扩展。...如果我们是直接使用系统提供的IEnumerableT>对象的话,只需要构建IEnumerableT>对象的扩展方法就能实现对集合类型的扩展。...IQueryableT>继承自IEnumerableT>接口,也就是可以被foreach语法调用的,但是在GetEnumerator方法中才会去执行提供程序的代码。...} 这是IQueryableT>接口中从IEnumerableT>继承下来的两个返回IEnumerator接口类型的方法,在我们目前使用的Linq to Sql、Linq to Entity中都会返回强类型的集合对象...方法的返回类型也是IQueryableT>类型,返回类型和扩展类型相同就已经构成链式编程的最小环路。
获取一个对象的枚举器可以调用对象的 GetEnumerator 方法。实现了 GetEnumerator 方法的对象称为可枚举(enumerable)对象。...foreach 语句就是用来配合可枚举类型一起使用的,他会执行下列行为: 调用 GetEnumerator 方法获取对象的枚举器 从枚举器请求每一项作为迭代变量(iteration variable)...可枚举类型是指实现了 IEnumerable 接口的类。...IEnumerable 只有一个函数成员: GetEnumerator: 获取可枚举类型的枚举器 using System.Collections; class MyClass : IEnumerable...泛型与非泛型版本的主要区别是: IEnumerable 接口的 GetEnumerator 方法要返回实现 IEnumerator 接口的枚举器实例 泛型版本的 Current 属性返回的不是 object
制造问题的是起头的这三个泛型的方法。如 selectByPrimaryKey这个方法,由于这是一个泛型方法,其返回值为T 。...而ServiceMock的录制回放的基本套路就是通过获取到被录制的方法的返回值类型来进行回放。...而如果是泛型的方法,那么returnType的结果就是“T”或者是”ListT>”, 这也就意味着以下反序列化方法的执行失败。...这样,只要获取到了切点中正在执行方法的返回值(原始类型或者是某个类的实例),然后根据返回值来获取到Class,并最终获取到Type。这样就可以继续愉快地进行反序列化了。...().equals("T") || returnType.getTypeName().equals("java.util.ListT>")) { 对于T 或者是ListT>的泛型方法,就在执行时获取一下执行类型并记录
在.NET6中微软新增了 TryGetNonEnumeratedCount 方法,让我们可以计算可枚举类型元素的总数。...: IEnumerableT> { public IEnumeratorT> GetEnumerator() { throw new NotImplementedException...(); } IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException...某些集合类型如果无法通过Count属性/方法确定集合元素数量的话,会严重影响程序性能,这是因为Count属性/方法必须枚举整个集合来确定元素数量,例如EF Core中使用IQueryable.Count...因此建议在代码中始终使用如下方式获取可枚举类型的元素总数: if (!
IEnumerable接口。并以一个virtual 方法的形式实现了该接口的GetEnumerator方法。(为什么用virtual方法的原因,我会再后续部分解释)。...EmployeeList的GetEnumerator是virtual方法导致不能充分利用Inlining的编译优化。...但是对应virtual方法调用的运行时对象类型而非其申明类型中定义的方法,在编译的时候,Complier是不可能获得某一个对象运行时属于什么类型的,所以它也不可能运用Inlining这种编译优化方案。...EmployeeList的GetEnumerator是virtual方法导致不能充分利用Inline的编译优化。 2....我们对EmployeeList的GetEnumerator方法作相应的修改使之返回我们重新定义个GenericEmployeeEnumerator。
IEnumerator接口为类内部的集合提供了迭代方式, IEnumerator 要求你实现三个方法: MoveNext方法:该方法将集合索引加1,并返回一个bool值,指示是否已到达集合的末尾。...Current方法: 返回position位置的当前对象 IEnumerable IEnumerable接口为foreach迭代提供了支持,IEnumerable要求你实现GetEnumerator方法...仅凭以上辞藻,很难区分两个接口的使用场景。 IEnumerator接口定义对类中的集合类型对象的迭代方式, IEnumerable接口允许使用foreach循环进行枚举。...因此IEnumerable接口的GetEnumerator方法会返回一个IEnumerator接口。要实现IEnumerable,你还必须实现IEnumerator。...语法糖初次接触可枚举的cars, 实际会访问cars实现的 GetEnumerator()方法,拿到迭代器 foreach每次迭代,实际会访问迭代器的Current属性
先来看一下IEnumerable接口,其实看过这个接口之后,发现它其实是非常的简单,只包含一个方法GetEnumerator(),它返回一个可用于循环访问集合的IEnumerator对象,如下面截图所示...直接对GetEnumerator()方法进行实现,然后返回IEnumerator即可。...,一个类型支持foreach遍历的条件可以是: 1、第一个方案是:这个类实现IEnumerable接口 2、第二个方案是:这个类有一个public的GetEnumerator的实例方法(不用继承...IEnumerable实现接口),并且返回类型中有public 的bool MoveNext()实例方法和public的Current实例属性。...实现了IEnmerableT>接口的集合,是强类型的。它为子对象的迭代提供类型更加安全的方式。 自己实现了下,感觉还是懂了一些,虽然还没有彻底的搞明白,但最起码大概知道怎么回事了。