基本数据类型 PowerShell本身是基于.Net开发出来的,所以在.Net中的基本数据类型,在PowerShell中也可以使用,只是在PowerShell中用”[]”来标识具体的数据类型。...我们也可以在定义变量时指定数据类型。比如我们要定义decimal类型的10,那么可以写为: [decimal]$c=10 $c.GetType() 可以看到我们的类型为Decimal。...而且哈希表的Key是不允许重复的,如果已经存在相同的值,添加会报错。...GetEnumerator方法,把哈希表转换后在执行Sort。...$a.GetEnumerator() | Sort-Object Name
IEnumerable接口定义非常简单,只有一个GetEnumerator()方法用于获取IEnumerator类型的迭代器。...每次调用GetEnumerator()方法时都需要创建一个新的对象,同时迭代器必须保存自身的状态,记录此时已经迭代到哪一个元素。这样枚举器就像是序列中的游标。...链表的第一个元素在数组中的索引号,当它的值为-1时表示此哈希地址不存在元素);另一个数组为entries,它用于存放哈希表中的实际数据,同时这些数据通过next指针构成多个单链表。...我们可以根据源码来模拟推导一下这个过程: 当添加第一个元素时,此时会分配哈希表buckets数组和entries数组的空间和初始大小,默认为3,关于初始数组的大小有大学问。...Dictionary查找元素的实现: **Dictionary**之所以能实现快速查找元素,其内部使用哈希表来存储元素对应的位置,我们可以通过哈希值快速地从哈希表中定位元素所在的位置索引
IEnumerable接口定义非常简单,只有一个GetEnumerator()方法用于获取IEnumerator类型的迭代器。 ?...每次调用GetEnumerator()方法时都需要创建一个新的对象,同时迭代器必须保存自身的状态,记录此时已经迭代到哪一个元素。这样枚举器就像是序列中的游标。...Dictionary内部有两个数组,一个数组名为buckets,用于存放由多个同义词组成的静态链表头指针(链表的第一个元素在数组中的索引号,当它的值为-1时表示此哈希地址不存在元素);另一个数组为entries...我们可以根据源码来模拟推导一下这个过程: 当添加第一个元素时,此时会分配哈希表buckets数组和entries数组的空间和初始大小,默认为3,关于初始数组的大小有大学问。...Dictionary之所以能实现快速查找元素,其内部使用哈希表来存储元素对应的位置,我们可以通过哈希值快速地从哈希表中定位元素所在的位置索引,从而快速获取到key对应的Value值。
它可以让用户透过特定的接口访问集合中的每一个元素而不用了解底层的实现。一般实现一个集合的方法有:数组,链表,哈希表等等,每种集合因为底层实现不同,遍历集合的方法也不同。...在.NET下,迭代器模式中的聚集接口和迭代器接口都已经存在了,其中IEnumerator接口扮演的就是迭代器角色,IEnumberable接口则扮演的就是抽象聚集的角色,只有一个GetEnumerator...,可在实现自定义集合类型迭代器模式时无需其他显式类,使用yield return语句可一次返回一个元素。...迭代器方法运行到yield return语句时,会返回一个expression,并保留当前在代码中的位置。下次调用迭代器函数时,将从该位置重新开始执行。...相反,会将调用的控制权返回到elements变量中。在foreach循环迭代时,将调用elements的MoveNext方法。
只需提供一个迭代器,即可遍历类中的数据结构,当编译器检测到迭代器时,他将自动生成IEnumerable接口的Current、MoveNext、Dispose方法。...2:迭代器创建可枚举类型 类a包含GetEnumerator方法和一个可枚举类型的迭代器,该可枚举类型迭代器内部又自动实现了GetEnumerator方法和一个可枚举类型 要想遍历该类a,类a的GetEnumerator...迭代器外的GetEnumerator方法获取迭代器内的GetEnumerator()方法,从而间接获得迭代器的枚举器,可对该总类进行遍历 public IEnumerable ib()...() { return ib().GetEnumerator(); } 2️⃣ 常见迭代器模式 迭代器返回枚举器 当我们实现返回枚举器的迭代器时,必须要实现GetEnumerator...也可枚举的方法:如果不实现总类的GetEnumerator方法,Main方法直接采用IEnumerable类型的迭代器(内有GetEnumerator方法),那么就不需要总类的GetEnumerator
实现了这个接口的类可以使用Foreach关键字进行迭代(迭代的意思是对于一个集合,可以逐一取出元素并遍历之)。实现这个接口必须实现方法GetEnumerator。...想知道如何实现方法GetEnumerator,不妨思考下实现了GetEnumerator之后的类型在Foreach之下的行为: 可以获得第一个或当前成员 可以移动到下一个成员 可以在集合没有下一个成员时退出循环...这是因为只有在ToList时,才真正开始进行迭代,获得迭代的成员。...在迭代的过程中改变集合的状态 foreach迭代时不能直接更改集合成员的值,但如果集合成员是类或者结构,则可以更改其属性或字段的值。不能在为集合删除或者增加成员,这会出现运行时异常。...在迭代时,只能前进不能后退。新的迭代不会记得之前迭代后值的任何变化。
到达 yield return 语句时,会记住当前在代码中的位置。 下次调用迭代器函数时,将从该位置重新开始执行。 通过 foreach 语句或 LINQ 查询从客户端代码中使用迭代器。 ...到达迭代器方法的结尾时,循环便已完成。...若要查看编译器执行的操作,可使用 Ildasm.exe 工具查看为迭代器方法生成的 Microsoft 中间语言代码。 为类或结构创建迭代器时,不必实现整个 IEnumerator 接口。...编译器检测到迭代器时,会自动生成 IEnumerator 或 IEnumerator 接口的 Current、MoveNext 和 Dispose 方法。...迭代器的使用 需要使用复杂代码填充列表序列时,使用迭代器可保持 foreach 循环的简单性。 需执行以下操作时,这可能很有用: 在第一次 foreach 循环迭代之后,修改列表序列。
它赋予集合迭代的能力。迭代是指从集合的头部,一个一个将元素拿出来,直到全部拿完为止的操作。迭代不能倒车,只能前进。IEnumerable是迭代器模式的实现。...通常将迭代中拿出来的元素称为iterator。 实现IEnumerable接口,必须实现它唯一的方法GetEnumerator。...方法GetEnumerator返回一个IEnumerator类型的输出。...IEnumerator类型又是一个接口,所以我们还要写一个类,并将这个类继承IEnumerator接口(实现它的2个方法),建立这个类的一个新实例,并传入一个数组(作为迭代的源)作为方法GetEnumerator...在遇到数组查重问题时,哈希永远都是一个利器:https://www.zhihu.com/question/31201024 IEnumerable最重要的一个派生类就是IList接口。
zls20210502,切记备注 加群,小编将会第一时间邀请你进群!...虽然StudentCollection里面有能用遍历的List,但我们不想在属性上迭代,我们想在类上迭代,不能 foreach(var s in sc.students){...}...下来按照IEnumetator接口的约定来实现我们的迭代器StudentCollectionEnumerator,用IDE自动补全代码如下: //迭代器 class StudentCollectionEnumerator...通过观察,发现迭代器主要就是返回一个元素对象,而StudentColletion里面的students元素集是List的,本身就能枚举,我们能不能利用这个不用专门写迭代器来实现枚举呢?...虽然第二种写法比较投机,充分利用了.NET Framework给的各种泛型集合可枚举的特征。不过我们也自己实现了一个GetEnumerator(),了解了枚举器的工作原理。本章学习目的达成。
Current方法: 返回position位置的当前对象 IEnumerable IEnumerable接口为foreach迭代提供了支持,IEnumerable要求你实现GetEnumerator方法...仅凭以上辞藻,很难区分两个接口的使用场景。 IEnumerator接口定义对类中的集合类型对象的迭代方式, IEnumerable接口允许使用foreach循环进行枚举。...所以执行一个Try…Catch块来捕获这个异常并引发InvalidOperationException异常, 提示在迭代时不允许修改集合内容。...“这也正是我们常见的在foreach 里面尝试修改迭代对象会报InvalidOperationException异常的原因。...语法糖初次接触可枚举的cars, 实际会访问cars实现的 GetEnumerator()方法,拿到迭代器 foreach每次迭代,实际会访问迭代器的Current属性
Iterator模式的几个要点 迭代抽象:访问一个聚合对象的内容而无需暴露它的内部表示。 迭代多态:为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。...迭代器的健壮性考虑:遍历的同时更改迭代器所在的集合结构,会导致问题。(所以 C# 中在 foreach 操作时,不允许更改集合,如果外部有更改,则会报错)。...一个集合类可以提供多个不同的 GetEnumerator 实现,如 GetEnumerator1,GetEnumerator2,返回不同的 IEnumerator,以实现不同的迭代功能。...(见下文) Part3 IEnumerator 与 yield 一个集合类想要支持被迭代,最主要的是构造一个 Enumerator 类,实现 IEnumerator 接口,在 GetEnumerator...Part5 线程安全 迭代显然是非线程安全的,每次 IEnumerable 都会生成新的 IEnumerator,从而形成多个互相不影响的迭代过程。 在迭代过程中,不能修改迭代集合,否则不安全。
{ // // 摘要: // 支持对非泛型集合的简单迭代。...2、枚举器实现了IEnumerator接口,所以它能做IEnumerator接口定义的所有工作 3、对于有枚举器的类型而言,必须有一个方法来获取它,获取一个对象枚举器的方法是调用对象的GetEnumerator...方法,实现GetEnumerator方法的类型叫做可枚举类型(enumerable),数组是可枚举类型 释义: 所以在此案例中,采用GetEnumerator()方法将获取到的数组的枚举器赋值给定义为枚举器类型的...ie,GetEnumerator()方法获取到的是返回的枚举器的实例 调用方法时MoveNext要在前,Current方法在后。...否则会出现枚举器还处于数组序列中第一项之前时,便先要输出的Current值,结果错误。
. 3、实战 单向链表 如下图,因为下一个节点对象没有保持上个节点的引用,所以这种链表称之为单向链表 实现代码如下,这边我使用了迭代器模式,方便节点的单向遍历,因为没有使用MS提供的标准的迭代器接口,...false; } } /// /// 当迭代器内部存在非托管资源时...false; } } /// /// 当迭代器内部存在非托管资源时...false; } } /// /// 当迭代器内部存在非托管资源时...return false; } } /// /// 当迭代器内部存在非托管资源时
迭代器对象必须跟踪自身遍历的进度。这使得多个迭代器可以相互独立地遍历同一集合。 集合(Collection)接口声明一个或多个方法来获取与集合兼容的迭代器。...请注意,返回方法的类型必须被声明为迭代器接口,因此具体集合可以返回各种不同种类的迭代器。 具体集合(Concrete Collections)会在客户端请求迭代器时返回一个特定的具体迭代器类实体。...但在特定情况下,客户端可以直接创建一个迭代器(例如当客户端需要自定义特殊迭代器时)。 实现方式 声明迭代器接口。该接口必须提供至少一个方法来获取集合中的下个元素。...如果你计划拥有多组不同的迭代器,则可以声明多个类似的方法。 为希望使用迭代器进行遍历的集合实现具体迭代器类。迭代器对象必须与单个集合实体链接。链接关系通常通过迭代器的构造函数建立。...检查客户端代码,使用迭代器替代所有集合遍历代码。每当客户端需要遍历集合元素时都会获取一个新的迭代器。
C# 1.0 使用foreach语句来实现访问迭代器的内置支持,foreach使便利集合变得更加容易,它比 for 语句更方便,也更容易理解,foreach被编译器编译后,会调用GetEnumerator...因为foreach就需要一个迭代器,IEnumerable接口中定义了一个GetEnumerator方法用来返回迭代器,类型如果实现了IEnumerable接口,则也必须实现GetEnumerator方法...,因此也就可以使用foreach语句了 在 C# 1.0 中,要获取迭代器,就必须要实现 IEnumerable或GetEnumerator 方法;而要实现一个迭代器,就必须要实现IEnumerable...public void Reset() { index = 0; } } } 从以上代码可以看出,在 C# 1.0 中,要使用某个类型可以迭代时要写大量代码的...,它的作用就是告诉编译器,GetEnumerator方法不是一个普通方法,而是实现迭代器的方法。
[TOC] 0x00 标准输入输出 Write-* 模块常用cmdlet命令: Get-Command write-* -CommandType Cmdlet | Select-Object -Property...The $Files location does not contain any XML files." 6.Write-Progress 命令 - 在PowerShell命令窗口中显示进度条。...当对象操作不太方便时,可以使用此cmdlet像在传统shell中一样搜索和操作字符串输出。...的命令,查看所有以Format打头的命令; Get-Command -Verb format | where {$_.Source -eq "Microsoft.PowerShell.Utility"...3.脚本块作为属性 # 在Powershell中文件的Length默认以byte作为单位如果你象让它输出时以KB显示 PS > ls | Format-Table Name,{ [int]($_.Length
可枚举对象可以是实现了 Ienumerable 或 Ienumerable 的对象,也可以是具有名为 GetEnumerator 方法并且方法返回一个枚举器的对象。...一个类如果实现了 IEnumerable 接口,那么就能够被迭代;调用GetEnumerator方法将返回IEnumerator接口的实现,它就是迭代器本身。...每当遇到 yield 时控制权都会回归到调用者那里,但是被调用者的状态还会保持。这个状态的生命周期绑定到了枚举器上,当调用这完成枚举之后状态就被释放。...内部的逻辑被反转并被切分到编译器生成的枚举器类中的 MoveNext 方法和 Current 属性里。这就意味着当你调用迭代器方法时,实际上时对编译器生成的类进行实例化。...当我们显示使用枚举器时如果没有释放掉枚举,那么将不会执行 finally 中的代码,为了避免这种情况的出现我们可以使用 using 语句。
/// /// 自定义泛型可迭代类型 /// /// /// This code shows how to build a instance...to an instance of any type that satisfies the following cond /// 1. has the public parameterless GetEnumerator..._capacity = capacity; _innerArray = new T[capacity]; } /// /// 可迭代对象中存储的对象数...private set; } = 0; public T this[int index] => _innerArray[index]; /// /// 向可迭代对象中添加元素.../// /// 当添加的元素数超过的值时,新添加的元素会覆盖之前的值
第二步:通过IEnumerable要求实现的GetEnumerator()方法返回一个IEnumerator(迭代器对象),实现该接口必须实现以下三个方法/属性: ?...当枚举数位于此位置时,对MoveNext 的后续调用也返回 false。如果最后一次调用 MoveNext 返回 false,则调用 Current 会引发异常。...第五步:分析原理 总结分析下上面的代码,实现foreach代码的基本原理如下: 1、编写自定义集合类,实现IEnumerable接口,通过GetEnumerator()方法返回一个迭代器对象实例. 2、...Important 3、将初始化完的类数组作为参数传递给迭代器类 4、编写迭代器类,create 构造函数,接收自定义集合类初始化完的类数组 5、实现IEnumerator(迭代器)接口,实现对应的三个方法...,通过编写三个方法发现,其实迭代器就是简单的对数组进行的操作 第六步:思考 经过上面的分析之后,发现其实foreach语句换成C#代码就是以下代码: Person[] persons ={
1.概要 主要思想和实现方式: 迭代器模式的主要思想是将数据的存储和遍历分离,使得客户端可以通过统一的接口遍历不同类型的集合,而不需要关心集合的具体实现。...IEnumerable接口定义了一个方法GetEnumerator(),该方法返回一个实现了IEnumerator接口的迭代器对象。...IEnumerator接口包含了MoveNext()方法,用于移动迭代器到集合的下一个元素,以及Current属性,用于获取当前元素的值。...适用场景: 当集合背后为复杂的数据结构,且希望对客户端隐藏其复杂性时,可以使用迭代器模式。迭代器封装了与复杂数据结构进行交互的细节,提供了简洁的遍历接口。...,返回一个迭代器对象 public IEnumerator GetEnumerator() { return new MyIterator(items); } }