IRONSOFTWAREHOME

C#中的產生介紹 - 它是什麼,如何使用,以及什麼時候有用

Intro to Yield in C#

Tim Corey

43m 58s

當您第一次接觸到C#中的yield關鍵字時,可能會感到困惑。 它到底是如何工作的? 什麼時候應該使用yield return而不是傳統的return語句? 為了全面了解,我們將依據Tim Corey優秀的YouTube教學進行詳細解釋:"Intro to Yield in C# - What it is, how to use it, and when it is useful"。

在本指南中,我們將通過時間戳標記引用Tim的影片中的具體點以便於導航,並包含實際範例來展示yield如何改變資料流、大型集合和延遲評估的處理方式。

介紹C#中的Yield關鍵字

Tim首先介紹yield關鍵字,並強調它對於第一次接觸的開發者來說通常令人困惑。他解釋說,yield語句允許方法暫停執行,保持其狀態,然後在下一次調用時從中斷的位置繼續。 Tim強調理解yield對於有效處理資料尤為重要,特別是處理大資料集或自定義迭代邏輯時。

設置簡單範例:Class Program和Static Void Main

為了避免分心,Tim在Visual Studio中建立了一個簡單的Console Appliation,稱為"YieldDemoApp"。

Yield在C#中的實際作用

Tim接著更深入地探討理論。 在2:04,他描述了yield行為:不再一次性處理整個集合,yield語句位於其位置,即像將拇指放入一本書中一樣,允許執行暫停並稍後恢復。

這種行為對於延遲執行至關重要,因為值僅在需要時生成,而不是事先全部計算。 Tim的描述清晰地奠定了理解yield return的基礎。

撰寫演示程式碼

在Class Program的static void Main方法中,他設置了基本的開模型和結束消息,如"Start of the app"和"End of the app",使用Console.WriteLine來幫助明確顯示流程,特別是當使用foreach迴圈時。

這個初始程式碼範例純粹關注於yield的實現,不涉及任何UI的複雜性。

建立PersonModel類

為了演示,Tim建立一個具有FirstName和LastName屬性和構造函式的PersonModel類。 當PersonModel物件被建立時,會列印一條消息,指示初始化了哪個使用者。 這有助於形象化物件何時被建立和何時被消耗。

這個簡單的生成程式碼步驟為使用自定義迭代器打下基礎。

構建DataAccess類並使用傳統的List返回

在5:06,Tim轉到DataAccess類,並用一個返回IEnumerable<PersonModel>的GetPeople方法。 最初,返回值是一個包含三個PersonModel實例的List:Tim Corey, Sue Storm, 和 Jane Smith。

這個迭代器方法在開始迭代之前立即將所有物件載入到記憶體中——這是Tim後來與使用yield作對比的一個重要點。

展示List的記憶體用量

運行foreach迴圈後,Tim顯示所有三個使用者都在讀取第一個元素之前建立。 這突出顯示了一個潛在問題,當處理大型集合或大資料集時——高記憶體用量。

Tim解釋說,如果我們有一千個使用者,即使我們只需要幾個,用一千個物件也會建立,導致記憶體分配效率低下。

變更到Yield Return以進行延遲執行

在10:01,Tim修改GetPeople使用yield return,而不是建立一個臨時集合 (如List)。 每個yield return語句直接生成一個PersonModel。

這關鍵程式碼在方法內允許延遲評估,foreach需要下一個元素時才生成。

Tim還澄清方法的返回型別必須是IEnumerable<PersonModel>,使用List會破壞延遲執行的目的。

除錯:編譯器生成Yield程式碼

Tim使用斷點逐步演示過程。 他顯示在第一次MoveNext調用之前,序列是空的。 只有當foreach需要下一個值時,編譯器會觸發迭代器塊並執行yield return num行,這會初始化並返回PersonModel。

Tim強調編譯器在底層生成專用的狀態機來管理暫停和恢復的執行。

使用Yield Return的好處和效率

Tim解釋為什麼yield如此高效:

  • 您可以一次獲取一個記錄。

  • 您可以限制需要的int數量。

  • 您避免將整個集合載入到記憶體中。

  • 您提高了可擴展性,特別是在處理大型文件或資料流時。

通過使用LINQ的.Take(2),Tim演示即使存在三個yield return語句,也只有兩個物件被初始化——強調延遲執行的作用。

實例:使用Yield的質數生成器

Tim在Generators類內構建一個新的靜態IEnumerable<int> GetPrimeNumbers()方法。 在這個無限迴圈中,Tim使用helper IsPrimeNumber(int number)函式來檢查其是否為質數。 如果數字是質數,他使用yield return number來發送它。

這個範例顯示yield對於安全地處理無限序列至關重要。

沒有yield,程式碼會因為無限的記憶體消耗而崩潰。 然而,使用yield,延遲執行確保根據需求生數。

使用Take()獲取質數

Tim然後演示如何安全地只提取固定數量的質數:

var primeNumbers = Generators.GetPrimeNumbers().Take(10000);

這段程式碼寫在static void Main中,能有效地只提取10,000個質數。

因為yield return逐個生成數字,記憶體使用量保持低。

自定義迭代:使用GetEnumerator和MoveNext

Tim進一步解釋如何手動控制迭代。

他建立一個var iterator = primeNumbers.GetEnumerator(),然後用int i的for迴圈並調用iterator.MoveNext()來手動獲取元素。

這種手動方法實現了自定義迭代——只有在需要時才請求下一個值,並顯示該方法從上次暫停的地方準確恢復。

常見錯誤:在Yield的集合上使用ToList()

在36:45,Tim警告:將yield序列轉換為List並用.ToList()會導致立即全面評估。

如果您在無限序列上調用.ToList(),您風險崩潰您的應用程式。

Tim強調yield return用於延遲評估,而調用.ToList()打破了這一模式,強制記憶體全面實現。

當使用LINQ方法時,Tim建議謹慎考慮在何處引入.ToList()。

總結:為什麼Yield是強大的工具

Tim在結束時強調,儘管yield關鍵字增加了輕微的負擔(持有狀態機),但因減少記憶體使用和延遲評估的好處,yield在處理以下方面是一個強大的工具:

  • 大資料集

  • 大文件

  • 自定義迭代器

  • 無限序列

  • 資料流

  • 延遲處理

他建議在不同專案中練習使用yield,以更深入地理解yield return並避免常見的陷阱。

Tim最後鼓勵觀眾分享他們在生產程式碼中如何使用yield。

結論

通過學習Tim Corey的影片,我們看到了yield關鍵字對C#帶來的巨大好處。 從建立自定義迭代器到有效管理大型集合,yield return使得函式返回更智能和更為記憶體高效。 無論您正在處理var number, var point, var reader, var connection, 或是大型資料集,掌握yield可以顯著提升您的C#編碼技能。

如果您以前沒有探索過使用yield,現在是通過簡單例子進行練習並更好地理解yield return如何在C#編譯器內部運作的絕佳時機。 一定要查看Tim的官方YouTube頻道以獲得更多見解豐富的影片。

Earn More by Sharing What You Love

Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Let's Stay in Touch!

Join our newsletter, you’ll get exclusive access on article updates. We value your privacy

Key in blue circle

立即免費取得 30 天試用金鑰

Your trial license will be sent to your email address

無任何限制。100% 解鎖。無需信用卡。

OR
bullet_checked無需信用卡或建立帳號無任何限制。100% 解鎖。無需信用卡。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried Iron Suite
獲取您的無義務諮詢
填寫以下表格或發送電子郵件至sales@ironsoftware.com
您的詳細資訊將始終保密。
被全球數百萬工程師信任
Iron Software的客戶標誌
立即獲取您的30天試用金鑰
無需信用卡或帳戶建立