[C#] 基于 yield 語句的迭代器邏輯懶執行

眾所周知, C# 可以通過 yield 語句來快速向 IEnumerator 或者 IEnumerable 類型的方法返回值返回一個元素. 但它還有另外一個特性, 就是其內部邏輯的懶執行. 每兩個 yield 語句之間的邏輯都是一個狀態, 只有在調用迭代器的 MoveNext 方法后, 才會執行下一個狀態的邏輯.

在文章中, 編譯后的代碼已經經過簡化和刪減, 以便于理解


迭代器方法的懶執行

舉一個簡單的例子:

IEnumerator SomeLogic()
{Console.WriteLine("hello world");yield return null;Console.WriteLine("fuck you world");
}

在調用的時候, 邏輯并不會被立即執行, 只有對其返回的迭代器調用 MoveNext 的時候, 才會繼續執行.

var enumerator = SomeLogic();enumerator.MoveNext();   // 打印 hello world
enumerator.MoveNext();   // 打印 fuck you world

迭代器方法的編譯

在 C# 中, 使用了 yield 語句的, 返回 IEnumerator 或 IEnumerable 的方法, 會由編譯器生成一個迭代器或可迭代類型, 在類型的內部包含該方法的邏輯.

例如上面提到的代碼, 它會被編譯成大概這樣:

IEnumerator SomeLogic()
{return new SomeLogicEnumerator();
}private sealed class SomeLogicEnumerator : IEnumerator, IDisposable
{private int state;private object current;object IEnumerator.Current{get{return current;}}public SomeLogicEnumerator(int state){this.state = state;}void IDisposable.Dispose(){}private bool MoveNext(){int num = state;if (num != 0){if (num != 1){return false;}state = -1;Console.WriteLine("AWA");return false;}state = -1;Console.WriteLine("QWQ");current = null;state = 1;return true;}bool IEnumerator.MoveNext(){//ILSpy generated this explicit interface implementation from .override directive in MoveNextreturn this.MoveNext();}void IEnumerator.Reset(){throw new NotSupportedException();}
}

我們可以看到, 在這個迭代器類型中, 有一個 state 字段存儲了當前的狀態, 而在 MoveNext 被調用時, 會切換當前狀態, 然后根據當前狀態執行對應邏輯.

當然, 如果你的迭代器邏輯稍微長一些, 它也是可以處理的.

IEnumerator SomeLogic()
{Console.WriteLine("QWQ");yield return 1;Console.WriteLine("AWA");yield return 2;Console.WriteLine("QJFD");yield return 3;Console.WriteLine("JWOEIJFOIWE");
}

它的 MoveNext 就變成了這樣:

private bool MoveNext()
{switch (state){case 0:Console.WriteLine("QWQ");current = 1;state = 1;return true;case 1:Console.WriteLine("AWA");current = 2;state = 2;return true;case 2:Console.WriteLine("QJFD");current = 3;state = 3;return true;case 3:state = -1;Console.WriteLine("JWOEIJFOIWE");return false;default:return false;}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/208489.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/208489.shtml
英文地址,請注明出處:http://en.pswp.cn/news/208489.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

澤攸科技二維材料轉移臺的應用場景及優勢

隨著二維材料的廣泛研究和各種潛在應用的開發,對于二維材料樣品的精密操控與轉移的需求日益增加。特別是一些新型二維材料的制備和器件集成制備中,需要在顯微鏡下對樣品進行觀察與定位,并能夠在微米甚至納米量級上精確移動和轉移樣品。 傳統…

集簡云 x 零售企業丨快速集成有贊商城和微盛企微管家,實現私域運營自動化

客戶介紹 某公司是一家知名的飲料廠商,自1998年成立以來,一直致力于研發和生產各種熱門飲品,如果汁、碳酸飲料、礦泉水等。因其獨特的口感和健康的品質深受消費者的喜愛。企業擁有多個知名品牌,享有極高的品牌知名度和市場份額。該…

BGP綜合

1、使用PreVal策略,確保R4通過R2到達192.168.10.0/24。 2、使用AS_Path策略,確保R4迪過R3到達192.168.11.0/24。 3、配置MED策略,確保R4通過R3到達192.168.12.0/24。 4、使用Local Preference策略,確保R1通過R2到達192.168.1.0…

Mac電腦系統管理:iStat Menus中文 for Mac

iStat Menus是一款強大而靈活的系統監控工具,可以幫助Mac用戶實時監控和管理自己的電腦。它提供了豐富的系統狀態和性能指標,可自定義的菜單欄圖標以及歷史數據記錄功能,讓用戶能夠全面了解和掌握電腦的運行情況。 實時系統監控:i…

Django的Auth模塊

Auth模塊 我們在創建好一個Django項目后執行數據庫遷移命令會自動生成很多表 其中有auth_user等表 Django在啟動之后就可以直接訪問admin路由,需要輸入用戶名和密碼,數據參考的就是auth_user表,并且必須是管理員才能進入 依賴于a…

flink1.12.4消費kafka 報錯 The coordinator is not available

報錯 You should retry committing the latest consumed offsets. Caused by: org.apache.kafka.common.errors.CoordinatorNotAvailableException: The coordinator is not available. 但是任務還在正常跑. 開源bug [FLINK-28060] Kafka Commit on checkpointing fails rep…

12.8 作業 C++

使用手動連接,將登錄框中的取消按鈕使用qt4版本的連接到自定義的槽函數中,在自定義的槽函數中調用關閉函數 將登錄按鈕使用qt5版本的連接到自定義的槽函數中,在槽函數中判斷ui界面上輸入的賬號是否為"admin",密碼是否為…

一篇文章熟練掌握 Axios

Axios是什么 Axios是一個基于Promise的網絡請求庫,作用于node.js和瀏覽器中。在服務端使用原生node.js http模塊,在客戶端使用XMLHttpRequest。是基于Promise對Ajax的封裝。 Axios的特性 從瀏覽器創建XMLHttpRequests從node.js創建http請求支持Promis…

基于OpenCV的人臉識別系統案例

基于OpenCV的人臉識別系統案例 人臉識別簡介代碼實現案例應用情況 下面將介紹如何使用Python和OpenCV庫構建一個簡單但強大的人臉識別系統。人臉識別是計算機視覺領域的一個重要應用,具有廣泛的實際用途,從安全門禁到娛樂應用。 人臉識別簡介 人臉識別是…

MySQL - 表達式With as 語句的使用及練習

目錄 8.1 WITH AS 的含義 8.2 WITH AS語法的基本結構如下: 8.3 練習題1 8.4 牛客練習題 8.1 WITH AS 的含義 WITH AS 語法是MySQL中的一種臨時結果集,它可以在SELECT、INSERT、UPDATE或DELETE語句中使用。通過使用WITH AS語句,可以將一個查…

量子芯片技術:未來的計算革命

量子芯片技術:未來的計算革命 一、引言 隨著科技的不斷發展,人類正在進入一個全新的技術時代,即量子時代。量子芯片技術作為這個時代的重要代表,正逐漸改變我們對計算和信息處理的理解。本文將深入探討量子芯片技術的基本原理、…

Navicat 技術指引 | 適用于 GaussDB 分布式的服務器對象的創建/設計

Navicat Premium(16.3.3 Windows版或以上)正式支持 GaussDB 分布式數據庫。GaussDB分布式模式更適合對系統可用性和數據處理能力要求較高的場景。Navicat 工具不僅提供可視化數據查看和編輯功能,還提供強大的高階功能(如模型、結構…

Java入門 EditPlus的安裝與配置講解

寫Java程序不建議使用EditPlus,首選idea社區版,其次是vscode, 然后是eclipse 。editplus說實話排不上號。 但既然小伙伴想了解一下怎么配置,這里就簡單說一下。 下載 首先是jdk,jdk是Java開發和運行的基礎&#xff…

EVT_WDF_DEVICE_PREPARE_HARDWARE API

NTSTATUS EVT_WDF_DEVICE_PREPARE_HARDWARE(__inWDFDEVICE Device,__inWDFCMRESLIST ResourcesRaw,__inWDFCMRESLIST ResourcesTranslated); 上面API中ResourcesRaw和ResourcesTranslated類型相同,那他們的區別是啥? 答: EVT_WDF_DEVICE_P…

【前端設計模式】之訪問者模式

引言 在前端開發中,我們經常需要處理復雜的對象結構和數據集合。這時候,訪問者模式就能派上用場了。訪問者模式允許我們將操作和數據結構分離開來,從而實現對復雜對象結構的優雅處理。 訪問者模式的特性 訪問者模式具有以下特性&#xff1…

iview Table實現跨頁勾選記憶功能以及利用ES6的Map數據結構實現根據id進行對象數組的去重

因為iview Table組件的勾選是選中當前頁的所有數據,當我們切到別的頁面時,會發送請求給后端,這個時候就會刷新我們之前頁碼已經選中的數據。現在有個需求就是,在我們選擇不同頁碼的數據勾選中之后,實現跨頁勾選記憶功能,就是說已經打鉤了的數據,不管切到哪一頁它都是打鉤…

AI聊天專題報告:ChatGPT全景圖聊聊技術產品和未來

今天分享的AI系列深度研究報告:《AI聊天專題報告:ChatGPT全景圖聊聊技術產品和未來》。 (報告出品方:LanguageX) 報告共計:22頁 爭論:ChatGPT算不算技術革命 回應吳軍老師“ChatGPT不算新技術…

Navicat 技術指引 | 適用于 GaussDB 分布式的模型功能

Navicat Premium(16.3.3 Windows 版或以上)正式支持 GaussDB 分布式數據庫。GaussDB 分布式模式更適合對系統可用性和數據處理能力要求較高的場景。Navicat 工具不僅提供可視化數據查看和編輯功能,還提供強大的高階功能(如模型、結…

Dubbo學習

一、整體架構設計分層 接口服務層(Service):該層與業務邏輯相關,根據provider和consumer的業務設計對應的接口和實現 配置層(Config):對外配置接口,以ServiceConfig和ReferenceConfig為中心 服…

cache 2.單機并發緩存

0.對原教程的一些見解 個人認為原教程中兩點知識的引入不夠友好。 首先是只讀數據結構 ByteView 的引入使用是有點迷茫的,可能不能很好理解為什么需要ByteView。 第二是主體結構 Group的引入也疑惑。其實要是熟悉groupcache,那對結構Group的使用是清晰…