認真CS丨yield迭代

2021-08-19 20:25:35 字數 4274 閱讀 6309

首先我們來說下迭代的目的:

迭代是將自定義類變為自定義類陣列,並遍歷它

在c#1.0和c#2.0這兩個版本中,c#2比c#1多了乙個更簡潔的迭代方法

1、定義單個類—>2、定義這個類的陣列的列舉器方法—>3、定義getenumerator方法—>4、對該類陣列賦值,並例項化3getenumerator方法,並將賦值的陣列作為實參傳入這個方法,進而傳到列舉器—>5、呼叫foreach,對該類陣列進行遍歷

using system;

using system.collections;

public class person

}public class peopleenum : ienumerator

public bool movenext()

public void reset()

public object current

catch (indexoutofrangeexception)}}

}public class people : ienumerable

public ienumerator getenumerator()

}class program

; people peoplelist = new people(peoplearray);

foreach(person p in peoplelist)

}}

定義:迭代器是c#2.0中的新功能,迭代器塊可以是方法主體、訪問器主體或運算子主體,他能夠使您在類或結構中支援foreach迭代,而不必實現整個ienumerable介面(不實現它其中的列舉器介面),只需提供乙個迭代器,即可遍歷類中的資料結構,當編譯器檢測到迭代器時,他將自動生成ienumerable介面的current、movenext、dispose方法。迭代器需引用system.collections.generic命名空間

移除c#1.0的列舉器方法peopleenum,在繼承了ienumerable介面的people類中,將getenumerator方法中**改為如下**,用迭代器建立列舉器

public ienumerator getenumerator()

}

即getenumerator方法不再需要列舉器了,而是內部的迭代器yield return語句告訴編譯器來自動為我們建立列舉器,yield return語句指定了列舉器中下乙個可列舉項

c#1我們要寫單個類、ienumerable介面的實現類(內有getenumerator方法)、列舉器類,才能在main方法例項該類陣列遍歷它,

c#2我們僅寫單個類、ienumerable介面的實現類,不必寫列舉器類,便可在main方法例項該類陣列並遍歷它了

案例

using system;

using system.collections.generic;

class myclass

public ienumeratorgetenumerator()

static void main()

}

類a包含getenumerator方法和乙個可列舉型別的迭代器,該可列舉型別迭代器內部又自動實現了getenumerator方法和乙個可列舉型別

要想遍歷該類a,類a的getenumerator方法需獲取可列舉型別的getenumerator方法,從而獲得可列舉型別迭代器內部的列舉器

a、迭代器建立class型別

using system;

using system.collections.generic;

class myclass

public ienumerableib()

;yield return new as ;

yield return new as ;

}public ienumeratorgetenumerator()

static void main()

}

b、迭代器建立string型別

using system;

using system.collections.generic;

class myclass

public ienumeratorgetenumerator()

static void main()

}

迭代器建立列舉器:僅生成了乙個列舉器,getenumerator方法直接獲取迭代器(迭代器返回列舉器)

public ienumeratorib()

public ienumeratorgetenumerator()

迭代器建立可列舉型別:生成了乙個列舉器和乙個getenumerator方法。迭代器外的getenumerator方法獲取迭代器內的getenumerator()方法,從而間接獲得迭代器的列舉器,可對該總類進行遍歷

public ienumerableib()

public ienumeratorgetenumerator()

當我們實現返回列舉器的迭代器時,必須要實現getenumerator來讓類可列舉,getenumerator方法返回由迭代器返回的列舉器

using system;

using system.collections.generic;

class myclass

public ienumeratorgetenumerator()

static void main()

}

我們可讓總類實現getenumerator來讓總類本身可被列舉,也可不實現來讓類本身不可列舉。但即使不實現getenumerator方法,也能實現列舉

a、實現總類的getenumerator方法:迭代器方法ib內自動建立了乙個列舉器和乙個getenumerator方法,如果實現總類的getenumerator方法,它返回迭代器方法ib返回的getenumerator方法(這個方法獲取到迭代器的列舉器),從而間接獲取到的ib內自動建立的列舉器

using system;

using system.collections.generic;

class myclass

public ienumeratorgetenumerator()

static void main()

}

b、不實現getenumerator也可列舉的方法:如果不實現總類的getenumerator方法,main方法直接採用ienumerable型別的迭代器(內有getenumerator方法),那麼就不需要總類的getenumerator方法了

using system;

using system.collections.generic;

class myclass

static void main()

}

在乙個類中產生多個可列舉型別,那麼就不能能實現getenumerator方法,因為可列舉型別的getenumerator方法主體有固定格式,無法再次寫個getenumerator方法,那樣就會重名,且main方法呼叫的也不知是哪個正確的getenumerator方法

乙個類產生多個可列舉型別,而是採用不實現getenumerator的方法,main方法直接呼叫返回可列舉型別的迭代器,即上文的「b、不實現getenumerator也可列舉的方法

using system;

using system.collections.generic;

class myclass

; public ienumerablemethod1()

public ienumerablemethod2()

static void main()

}

public ienumeratorshuxing

}

上文講述的都是將迭代器作為方法。再次重申一下,迭代器塊可作為方法主體、訪問器塊主體和運算子主體

在編譯器生成的ienumerator列舉器方法中,reset方法(用來重置)並沒有實現,因此呼叫它會丟擲system.notspportedception異常。

認真CS丨堆疊

堆疊 stack 代表了乙個後進先出的物件集合。當向堆疊列表中新增一項,稱為推入元素。當從堆疊列表中移除一項時,稱為彈出元素。堆疊使用方法如下 stackobjs new stack objs.clear 移除 堆疊objs 所有元素 bool iscon objs.contains gameobj...

認真CS丨列舉器

實現了ienumerator介面的類稱為列舉器 using system.runtime.interopservices namespace system.collections 摘要 將列舉數推進到集合的下乙個元素。返回結果 如果列舉數已成功地推進到下乙個元素,則為 true 如果列舉數傳遞到集合...

認真CS丨泛型

為什麼要用泛型?那麼先來看下面兩個功能相似的非泛型類 這個類都是int class myintstack 這個類都是float class myfloatstack 第乙個類實現了int型的功能,第二個類通過剪下 改類名 將int改為float實現float型功能,通過這種方式的變換實現float型...