原因是C#中自定义集合类型要实现foreach的功能,必须通过IEnumerator和IEnumerable两个接口来实现!...2、通过IEnumerator和IEnumerable两个接口实现自定义集合类型的foreach循环功能....第一步:实现自定义集合类型实现IEnumerable接口,实现该接口的字面意思可以理解为:自定义集合类型实现了该接口,就拥有了"可枚举的功能".代码如下: ?...第五步:分析原理 总结分析下上面的代码,实现foreach代码的基本原理如下: 1、编写自定义集合类,实现IEnumerable接口,通过GetEnumerator()方法返回一个迭代器对象实例. 2、...Important 3、将初始化完的类数组作为参数传递给迭代器类 4、编写迭代器类,create 构造函数,接收自定义集合类初始化完的类数组 5、实现IEnumerator(迭代器)接口,实现对应的三个方法
之前我们说过可以使用 foreach 来遍历数组元素,本篇来讨论为什么数组可以使用 foreach 语句处理,我们可以还使用迭代器来使得自定义类型也可以使用 foreach。...枚举器和可枚举类型 为什么数组可以使用 foreach 呢?因为数组可以提供一个枚举器(enumerator)对象。枚举器对象可以依次返回数组元素。...foreach 语句就是用来配合可枚举类型一起使用的,他会执行下列行为: 调用 GetEnumerator 方法获取对象的枚举器 从枚举器请求每一项作为迭代变量(iteration variable)...current = (int)ie.Current; Console.WriteLine(current); } } } IEnumerable 可枚举类型是指实现了...IEnumerable 只有一个函数成员: GetEnumerator: 获取可枚举类型的枚举器 using System.Collections; class MyClass : IEnumerable
另外假如泛型类型定义了静态构造器,那么针对每一个封闭类型,都会执行一次。泛型类型定义静态构造器的目的是保证传递的类型实参满足特定的条件。...例如,由于List从Object派生,所以List和List也从Object派生。指定类型实参不影响继承层次结构。...泛型的验证和约束 前面我们提到,使用静态构造器来约束泛型,我们可以这样定义只能处理枚举类型的泛型类型: class GenericTypeThatRequireAnEnum { static...构造器约束 主要约束 为类型参数指定一个引用类型约束。相当于向编译器承诺:一个指定的类型实参要么是约束类型相同的类型,要么是从约束类型派生的类型。...包括枚举在内的任何值类型都满足这个约束,但是Nullable值类型除外,编译器和CLR认为它是特殊类型。
可枚举对象可以是实现了 Ienumerable 或 Ienumerable 的对象,也可以是具有名为 GetEnumerator 方法并且方法返回一个枚举器的对象。...data + 1; } } 上述代码中用到了 yield return , yield return 语句的意思是请求从枚举器产生的下一个元素。...这个状态的生命周期绑定到了枚举器上,当调用这完成枚举之后状态就被释放。 2.原理 编译器把地带方法转换成私有的,实现了 IEnumerable 或者 IEnumerator 的类。...} } static IEnumerable Foo() { yield return 1; yield return 2; yield return 3; } 迭代器中的 return... GetNum(IEnumerable sequence) { foreach (int x in sequence) {
在编程语言中,迭代器是一种可以遍历容器(如列表或数组)的元素的对象。在C#中,我们可以使用yield关键字创建自定义的迭代器。...yield是一个强大的关键字,它使我们能够使用简洁、清晰的语法来创建和管理迭代器。 什么是Yield? 在C#中,yield关键word用于指定一个迭代器块,也就是提供可枚举接口实现的方法。...Yield的使用方法 让我们通过一个例子来看看如何使用yield: public static IEnumerable GetNumbers() { for (int i = 0; i...让我们看一个例子: public static IEnumerable GetNumbers() { for (int i = 0; i < 10; i++) {...例如,下面这个函数可生成一个无限的整数序列: public static IEnumerable GenerateInfiniteSequence() { int i = 0;
作为参数传递到 SelectMany() 的转换函数必须为每个源值返回一个可枚举值序列。 然后,SelectMany() 串联这些可枚举序列,以创建一个大的序列。...在每种情况下,假定选择器(转换)函数从每个源值中选择一个由花卉数据组成的数组。 下图描述 Select() 如何返回一个与源集合具有相同元素数目的集合。 ?...List numbers = new List() { 35, 44, 200, 84, 3987, 4, 199, 329, 446, 208 }; IEnumerable...本表中名称以“As”开头的转换方法可更改源集合的静态类型,但不对其进行枚举。 名称以“To”开头的方法可枚举源集合,并将项放入相应的集合类型。...方法 方法名 说明 C# 查询表达式语法 详细信息 聚合 对集合的值执行自定义聚合运算。 不适用。
后记 一、一个很简单的例子 下面是一个很简单的例子:Vector为自定义表示二维向量的类型,Program的静态方法GetVetors方法获取以类型为IEnumerable...针对上面这个例子,我们对其进行简单的修改来验证“延迟赋值”的存在。...从中我们清楚地但到,对Vector对象的创建发生在每一个迭代中。...IEnumerable这个接口和集合没有本质的联系,只是提供“枚举”的功能。甚至说,我们应该将IEnumerable对象当成“只读”的,如果我们需要“可写”的功能,你应该使用数组或者集合类型。...至于本文提到的“延迟赋值”或者“延迟计算”,如果就“枚举”功能而言,也不是很准确,因为“枚举”不承诺“赋值”。
迭代器模式的优点 1.访问一个聚合对象的内容而无须暴露它的内部表示。 2.遍历任务交由迭代器完成,这简化了集合类。 3.它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。...一个集合可以有多个“书签”,移动其中任何一个都可以枚举集合,与其他枚举器互不影响。...可在实现自定义集合类型迭代器模式时无需其他显式类,使用yield return语句可一次返回一个元素。...迭代器方法运行到yield return语句时,会返回一个expression,并保留当前在代码中的位置。下次调用迭代器函数时,将从该位置重新开始执行。...迭代器执行过程 以下代码从迭代器方法返回IEnumerable,然后遍历其元素。
如果某个类型实现了IEnumerable接口,就意味着它可以被迭代访问,也就可以称之为集合类型(可枚举)。...每次调用GetEnumerator()方法时都需要创建一个新的对象,同时迭代器必须保存自身的状态,记录此时已经迭代到哪一个元素。这样枚举器就像是序列中的游标。...我们可以自己实现IEnumerable接口和IEnumerator接口实现自定义集合。...实现自定义可枚举类型: public class MySet : IEnumerable { internal object[] values; public MySet(object...ICollection和ICollection 从第一张图中,我们可以得知ICollection继承于IEnumerable接口,并且扩展了IEnumerable接口。 ?
如果某个类型实现了IEnumerable接口,就意味着它可以被迭代访问,也就可以称之为集合类型(可枚举)。...每次调用GetEnumerator()方法时都需要创建一个新的对象,同时迭代器必须保存自身的状态,记录此时已经迭代到哪一个元素。这样枚举器就像是序列中的游标。...我们可以自己实现IEnumerable接口和IEnumerator接口实现自定义集合。...实现自定义可枚举类型: public class MySet : IEnumerable { internal object[] values; public MySet(object...ICollection和ICollection 从第一张图中,我们可以得知**ICollection继承于IEnumerable接口,并且扩展了IEnumerable**接口。
引言 「yield」关键字是 C# 中的一种语言特性,用于在枚举器中简化迭代器的实现。...它使得开发人员可以通过定义自己的迭代器来简化代码,而不必手动实现 IEnumerable 和 IEnumerator 接口。...当执行到yield return语句时,代码将会暂停执行,将返回值传递给迭代器的调用者,并将迭代器的状态保存下来。...Console.Write(i + " "); } Console.ReadKey(); } static IEnumerable...总结 使用 yield 关键字可以将一个方法转换为一个返回可枚举对象或迭代器的方法,而不必手动实现 IEnumerable 和 IEnumerator 接口 使用 yield 来创建异步生成器,在某些场景下可以实现更高效
在 C# 中,迭代器模式可以通过实现IEnumerable和IEnumerator接口来实现。...迭代器实现 public class MyCollection : IEnumerable { private int[] items = new int[5] { 31, 12, 3,...64, 51 }; // 实现 IEnumerable 接口,返回一个枚举器 public IEnumerator GetEnumerator() { return...new MyEnumerator(items); } // 自定义迭代器类 private class MyEnumerator : IEnumerator {...此外,通过实现IEnumerable和IEnumerator接口,我们可以轻松地在 C# 中实现迭代器模式。 foreach是C#语法糖,用来遍历实现了IEnumerable接口的集合类。
不要在枚举中包含sentinel值(多个名字一个值) 1.8.7. 要为简单枚举提供零值 1.8.8. 一般使用Int32为载体来实现枚举 1.8.8.1....避免下列之外的类型来做索引器的参数 System.Int32 System.Int64 System.String System.Object 枚举 泛型 2.2.7.5....如为所有的IEnumerable的实现类增加了一个LINQ的功能(很多方法) 2.6.2.2....要验证枚举参数 不要以为用户传入的枚举参数值一定会在定义范围内。...不要用Enum.IsDefined来检查枚举的范围 负载很高,容易误用 2.8.7.5. 要清楚的知道传入的可变参数可能会在验证后发生改变 最好先制作一个副本,再验证和处理 2.8.8.
以下的示例演示了如何创建一个IEnumerable类型的空集合: var q = Enumerable.Empty(); Console.WriteLine(q == null...下面的示例演示了使用Range操作符来生成从0到9的整数序列: var q = Enumerable.Range(0, 10); foreach (var item in q) {...名称以“As”开头的转换方法可更改源集合的静态类型但不枚举(延迟加载)此源集合。名称以“To”开头的方法可枚举(即时加载)源集合并将项放入相应的集合类型。 1....ToDictionary ToDictionary操作符根据指定的键选择器函数,从IEnumerable创建一个Dictionary。...它也可以像First方法一样传递一个条件。需要说明的是如果序列中不包含任何元素,返回的默认值是个怎样的元素。
C#中的枚举器(译) 翻译文章,原文链接(已失效):http://www.ondotnet.com/pub/a/dotnet/2004/06/07/liberty.html 如果你正在创建一个表现和行为都类似于集合的类...构造函数将对数组进行初始化并使用传递进来的参数填充它。...你可以通过ListBoxEnumerator的构造函数来传递。...在这个例子的2.0版本中,我重写上面的列表,使用C# 2.0的两个新特性:泛型 和 枚举器。...更进一步,由枚举器所返回的值一定是string类型,如果你想要返回其他类型,你可以修改IEnumerable泛型语句,IEnumerable泛型语句将反射新类型。
这个关键字在开发过程当中不长用到 说yield之前要先说一下IEnumerable 接口 IEnumerable 接口 : 公开枚举数,该枚举数支持在非泛型集合上进行简单迭代。...简单的迭代就是指foreach循环了 yield关键字: 在迭代器块中用于向枚举数对象提供值或发出迭代结束信号 枚举数对象就好比foreach(object o in objectList)中的o 在下面的示例中...,迭代器块(这里是方法 Power(int number, int power))中使用了 yield 语句。...当调用 Power 方法时,它返回一个包含数字幂的可枚举对象。注意 Power 方法的返回类型是 IEnumerable(一种迭代器接口类型)。...当最后一种yield流程结束时,就相当于计数器归零。
例如,可以从程序集a或程序集b中的所有类访问ClassA的PublicF。 类型和类型成员的访问修饰符, 类型(类、结构、枚举、接口、委托等)只能有内部和公共访问修饰符。...IEnumerable vs. IEnumerator 这些都是向前使用的,并且只读取一个集合的访问权限。 ? IEnumerable使用IEnumerator,它可以与foreach语句一起使用。...IEnumerable 以从内存集合中查询数据(比如,列表) 它在内存中加载数据(服务器端到客户端),同时从数据库查询数据,然后过滤客户端数据。 不支持自定义查询。 不支持延迟加载。...IQueryable 可以从内存之外查询数据(服务器端类、远程数据库、web服务) 它在数据库查询时过滤服务器端的数据,然后发送到客户端。...valueA = 5; int inputAndOutputValueB = 6; int inputOnlyValueC = 7; int outputOnlyValueD;
在ActionInvoker对Action的执行过程中,除了通过利用ActionDescriptor对Action方法的执行,以及之前进行的Model绑定与验证之外,还具有一个重要的工作,那就是对相关筛选器...[本文已经同步到《How ASP.NET MVC Works?》...通过上面的代码片断我们可以看到FilterScope的5个枚举选项均被设置了一个值,这个值决定了Filter的执行顺序,具有更小的枚举值会被优先执行。...Order { get; } 14: } 从应用在FilterAttribute上的AttributeUsageAttribute的定义可以看出该特性可以应用在类型和方法上,这意味着筛选器一般都可以应用在...我们现在就来通过实例来验证这一点。
IEnumerator接口定义对类中的集合类型对象的迭代方式, IEnumerable接口允许使用foreach循环进行枚举。...“从英文词根上讲: IEnumerator接口代表了枚举器,里面定义了枚举方式,是名词。 IEnumerable接口代表该对象具备了可被枚举的性质,是形容词。...总之,如果您想提供对foreach的支持,那么就先让对象可枚举,再谈论枚举方式,也就是说实现这两个接口。 最佳实践 在嵌套类中实现IEnumerator,这样你可以创建多个枚举器。...private class MyEnumerator:IEnumerator { public car[] carlist; int...cars, 实际会访问cars实现的 GetEnumerator()方法,拿到迭代器 foreach每次迭代,实际会访问迭代器的Current属性
IEnumerator 和 IEnumerable 通俗话讲: 能不能 foreach就看你遍历对象有没有实现 IEnumerable,就说明你是不是一个 可枚举类型( enumerator type)...public interface IEnumerable{ IEnumerator GetEnumerator();} 是不是个枚举器( enumerator)就看你实现了 IEnumerator...(yield官方文档) 其实迭代器(iterator)就是为了更简单的创建枚举器(enumerator)和可枚举类型(enumerator type)的方式 如果枚举器和可枚举类型还是不理解(举个例子)...就懂了:(从遍历方式就看出区别了) 定义一个斐波拉契函数,返回可枚举类型 /// /// 返回一个可枚举类型/// public static IEnumerable.../// /// 返回一个枚举器/// public static IEnumerator FibonaByIEnumerator(int n){
领取专属 10元无门槛券
手把手带您无忧上云