如何重複使用IEnumerable物件來列舉?

2021-09-06 19:53:11 字數 1114 閱讀 7468

我在2023年9月發表了乙個問問,

沒人理我。

自己看了一下,嘗試自己解決:

原問題:

msdn: 在非泛型集合中,您可以在呼叫reset後呼叫movenext,將列舉數移回集合的開始處。

在泛型集合中,您不能再將current設定為集合的第乙個元素;而須建立新的列舉數例項。

乙個複雜的linq 變數停難定義的,有時候要重複使用幾次,但是msdn裡面說要重新建立,難道又要書寫一次linq**麼?或者產生拷貝就可以?

請給出重複使用該列舉變數的解決方案。

另外:msdn:

只要該集合保持不變,列舉數也就保持有效。如果對該集合進行了更改(例如新增、修改或刪除了元素),該列舉數將失效(這一變化是不可逆轉的),且其行為將變為未定義。

假設我定義了乙個列舉數,但是還沒使用,然後資料來源發生變化,我這個列舉數就沒有用了麼?

為什麼泛型集合沒有reset的實現?我認為是有些資料來源回到首個元素比較浪費效能,甚至不可能,比如網路流。

列舉變數要求源不可以變,因為列舉變數是乙個位置資訊,源結構發生變化,增加或者減少,位置資訊很可能變得沒有意義,但不是一定。

觀察一下列舉器的一般實現(yield生成**),首先是在資料來源裡面產生乙個內部類(列舉器),當foreach 呼叫資料來源的getenumerator(), new 這個內部類的例項,該例項就儲存了當前資料來源中位置資訊。其他自定義的資料來源也是類似的原理。

當源發生變化,位置資訊沒有義務要發生相應的變化,這不是設計規範,大部分實現可以做到,但是也不排除特殊情況,而資料來源的設計是乙個高度適用的方案,因此無法保證修改後位置資訊還是有效的。

第二個問題是,如何重複使用列舉器。列舉器是乙個不斷movenext的位置變數,不能往回走,提出這個問題本身就不是乙個好的問題。為何當初我會提出,主要是我沒有理解列舉器的實現機制,沒有將linq語句和產生列舉器這點區分開來,我以為書寫乙個複雜的linq語句,產生乙個列舉器之後,這個語句又要重新書寫。那是因為沒有理解foreach 呼叫了資料來源的getenumerator()函式,這個函式建立了乙個全新的列舉器,也就是根本可以直接使用這個資料來源,重用這段linq語句,foreach會產生全新的列舉器,不需要我擔心。

如何重複使用TIMER 避免計時累加

計時操作 改變介面的倒計時資訊 private void timeroperation mtimer.schedule timertask,progress delay,progress period 在關閉時使用 private void closetimer if mtimer null 不然,...

VirtualBox 如何重複使用複製的硬碟檔案

virtualbox 中,如果複製了乙個硬碟檔案 vdi 還希望在新建的虛擬機器中使用該檔案,會報錯,告訴你這個檔案的uuid已經有了,對不起,用不了。這點就不如人家vmware做的好,人家會問你是不是拷貝的呀什麼的,多溫柔體貼。而這時候,virtualbox簡直就是一刁蠻任性的公主,讓人頭疼。沒辦...

可重複使用SQL指令碼

1.新建乙個test.sql,適用於新增字段 dml 但不確定是否含有該欄位,內容如下 num number begin select count 1 into num from user tab columns where table name table1 and column name col...