IRONSOFTWAREHOME

Wprowadzenie do Yield w C# - Czym jest, jak go używać i kiedy jest przydatny

Intro to Yield in C#

Tim Corey

43m 58s

Gdy po raz pierwszy natkniesz się na słowo kluczowe yield w C#, może to wydawać się zagmatwane. Jak dokładnie to działa? Kiedy powinieneś używać yield return zamiast tradycyjnej instrukcji return? Aby zrozumieć to w pełni, przeprowadzimy szczegółowe wyjaśnienie oparte na doskonałym tutorialu na YouTube autorstwa Tima Coreya: "Intro to Yield in C# - What it is, how to use it, and when it is useful".

W tym przewodniku odwołamy się do określonych punktów wideo Tima z oznaczeniem czasu, aby ułatwić nawigację i zawrzeć praktyczne przykłady pokazujące, jak yield zmienia sposób, w jaki obsługujesz strumienie danych, duże kolekcje i leniwą ewaluację.

Wprowadzenie do slowa kluczowego Yield w C#

Tim zaczyna od przedstawienia słowa kluczowego yield i podkreślenia, że to często może być mylące dla programistów, którzy spotykają się z tym po raz pierwszy. Wyjaśnia, że instrukcja yield pozwala metodzie na wstrzymanie wykonania, zachowanie swojego stanu, a następnie kontynuowanie od miejsca, w którym została wstrzymana przy następnym wywołaniu. Tim podkreśla, że zrozumienie yield jest kluczowe do efektywnego przetwarzania danych, szczególnie w przypadku dużych zbiorów danych lub implementacji logiki iteracji niestandardowej.

Przygotowywanie prostego przykładu: Klasa Program i Static Void Main

Aby wyeliminować rozproszenia, Tim tworzy prostą aplikację konsolową w Visual Studio o nazwie YieldDemoApp.

Co Yield rzeczywiscie robi w C#

Następnie Tim zagłębia się w teorię. O godzinie 2:04 opisuje zachowanie yield: zamiast przetwarzać całą kolekcję naraz, instrukcja yield utrzymuje miejsce — tak, jakby włożyć kciuk do książki — aby można było wstrzymać wykonanie i wznowić je później.

To zachowanie jest kluczowe dla opóźnionego wykonania, gdzie wartości są generowane tylko wtedy, gdy są potrzebne, zamiast wszystko wyliczać z góry. Opis Tima wyraźnie ustanawia podstawę do zrozumienia, jak działa yield return.

Pisanie kodu demo

W metodzie static void Main klasy Program ustawia podstawowe komunikaty takie jak "Początek aplikacji" i "Koniec aplikacji" za pomocą Console.WriteLine, pomagając wyraźnie zobaczyć przepływ podczas pracy z pętlą foreach.

Ten początkowy przykład kodu koncentruje się wyłącznie na implementacji yield bez wprowadzania złożoności interfejsu użytkownika.

Tworzenie klasy PersonModel

Aby zademonstrować, Tim tworzy klasę PersonModel z właściwościami FirstName i LastName oraz konstruktorem. Gdy zostanie utworzony obiekt PersonModel, drukowany jest komunikat wskazujący, który użytkownik został zainicjowany. To pomaga zobaczyć, kiedy obiekty są tworzone, a kiedy są konsumowane.

Ten prosty krok generowania kodu tworzy scenę do pracy z niestandardowymi iteratorami.

Tworzenie klasy DataAccess z tradycyjnym zwróceniem listy

O 5:06 Tim przechodzi do klasy DataAccess z metodą GetPeople zwracającą IEnumerable<PersonModel>. Początkowo wartość zwracana to lista wypełniona trzema instancjami PersonModel: Tim Corey, Sue Storm i Jane Smith.

Ta metoda iteratora ładuje wszystkie obiekty od razu do pamięci przed rozpoczęciem iteracji — jest to ważny punkt, który Tim później kontrastuje z użyciem yield.

Demonstracja użycia pamięci za pomocą List

Po uruchomieniu pętli foreach Tim pokazuje, że wszyscy trzej użytkownicy są tworzeni przed odczytem pierwszego elementu. To ukazuje potencjalny problem przy obsłudze dużych kolekcji danych — wysokie zużycie pamięci.

Tim wyjaśnia, że gdybyśmy mieli na przykład tysiąc użytkowników, stworzylibyśmy tysiąc obiektów, nawet gdybyśmy potrzebowali tylko kilku, co skutkuje nieefektywną alokacją pamięci.

Zmiana na Yield Return dla opóźnionego wykonania

O 10:01 Tim modyfikuje GetPeople, aby użyć yield return zamiast tworzenia tymczasowej kolekcji (List). Każda instrukcja yield return bezpośrednio emituje jeden obiekt PersonModel naraz.

Ten kluczowy kod wewnątrz metody pozwala na leniwą ewaluację, gdzie następny element jest generowany tylko wtedy, gdy jest potrzebny przez foreach.

Tim także wyjaśnia, że typ zwracanej metody musi być IEnumerable<PersonModel>, a użycie List unieważniło by cel opóźnionego wykonania.

Debugowanie: Jak kompilator generuje kod dla Yield

Tim używa punktów przerwania, aby prześledzić proces. Pokazuje, że przed pierwszym wywołaniem MoveNext sekwencja jest pusta. Dopiero gdy foreach potrzebuje następnej wartości, kompilator uruchamia blok iteratora i wykonuje linię yield return num, która inicjuje i zwraca PersonModel.

Tim podkreśla, że kompilator generuje specjalne maszyny stanów, aby zarządzać wstrzymanym i wznowionym wykonaniem.

Zalety i efektywność używania Yield Return

Tim wyjaśnia, dlaczego yield jest taki efektywny:

  • Możesz pobierać jeden rekord na raz.

  • Możesz ograniczyć potrzebną liczbę int.

  • Unikniesz ładowania całej kolekcji do pamięci.

  • Poprawisz skalowalność, szczególnie podczas pracy z dużymi plikami lub strumieniami danych.

Za pomocą metody LINQ's .Take(2), Tim pokazuje, jak tylko dwa obiekty są inicjalizowane, mimo że istnieją trzy instrukcje yield return — podkreślając działanie opóźnionego wykonania.

Praktyczny przykład: Generator liczb pierwszych przy użyciu Yield

Tim buduje nową metodę static IEnumerable<int> GetPrimeNumbers() wewnątrz klasy Generators. W tej nieskończonej pętli Tim używa pomocniczej funkcji IsPrimeNumber(int number) do sprawdzenia pierwszości. Jeśli liczba jest pierwsza, używa yield return number, aby ją wyemitować.

Ten przykład pokazuje, że yield jest kluczowy do bezpiecznego obsługiwania nieskończonych sekwencji.

Bez yield kod zawaliłby się z powodu nieograniczonego użycia pamięci. Jednak użycie yield zapewnia, że opóźnione wykonanie generuje liczby na żądanie.

Pobieranie liczb pierwszych za pomocą Take()

Następnie Tim pokazuje, jak bezpiecznie pobierać tylko stałą liczbę liczb pierwszych:

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

Ten kod napisany wewnątrz static void Main efektywnie pobiera tylko 10 000 liczb pierwszych.

Ponieważ yield return produkuje liczby jedna po drugiej, zużycie pamięci pozostaje niskie.

Niestandardowa iteracja: Używanie GetEnumerator i MoveNext

Tim rozwija temat, wyjaśniając, jak kontrolować iterację ręcznie.

Tworzy var iterator = primeNumbers.GetEnumerator(), a następnie używa pętli for z int i i wywołuje iterator.MoveNext(), aby ręcznie pobierać elementy.

To podejście ręczne umożliwia niestandardową iterację — proszenie o następny element tylko wtedy, gdy jest potrzebny, i pokazując, że metoda wznawia się dokładnie od miejsca, w którym została wstrzymana.

Częsty błąd: Używanie ToList() na kolekcjach yield

O 36:45 Tim ostrzega: konwertując sekwencję yield na List za pomocą .ToList() powoduje natychmiastową pełną ewaluację.

Jeśli wywołasz .ToList() na nieskończonej sekwencji, ryzykujesz zawaleniem aplikacji.

Tim podkreśla, że yield return jest przeznaczony do leniwej ewaluacji, a wywołanie .ToList() łamie ten schemat, wymuszając pełną materializację pamięci.

Pracując z metodami LINQ, Tim zaleca ostrożność w kwestii, gdzie wprowadzasz .ToList().

Podsumowanie: Dlaczego Yield jest potężnym narzędziem

Tim podsumowuje, podkreślając, że chociaż słowo kluczowe yield dodaje pewne obciążenie (utrzymywanie ma-szyny stanów), korzyści w postaci zmniejszonego zużycia pamięci i leniwej ewaluacji czynią go potężnym narzędziem przy pracy z:

  • Duże zbiory danych

  • Duże pliki

  • Niestandardowe iteratory

  • Nieskończone sekwencje

  • Strumienie danych

  • Przetwarzanie odroczone

Sugeruje praktykowanie użycia yield w różnych projektach, aby zdobyć głębsze zrozumienie yield return i uniknąć typowych pułapek.

Tim kończy zapraszając widzów do podzielenia się, jak używali yield w kodzie produkcyjnym.

Wnioski

Przechodząc przez video Tima Corey'a "video", dostrzegliśmy ogromne korzyści, jakie słowo kluczowe yield wprowadza do C#. Od tworzenia niestandardowych iteratorów do efektywnego zarządzania dużymi kolekcjami, yield return pozwala na mądrzejsze i bardziej pamięciooszczędne funkcje. Niezależnie od tego, czy pracujesz z var number, var point, var reader, var connection, czy dużymi zbiorami danych, opanowanie yield może dramatycznie podnieść twoje umiejętności kodowania w C#.

Jeśli nie eksplorowałeś wcześniej użycia yield, teraz to doskonały moment, aby poćwiczyć poprzez proste przykłady i lepiej zrozumieć, jak yield return działa wewnątrz kompilatora C#. Sprawdź oficjalny Kanał YouTube Tima, aby obejrzeć więcej inspirujących filmów.

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

Uzyskaj natychmiast swój darmowy 30-dniowy Klucz Testowy.

Your trial license will be sent to your email address

Brak ograniczeń. 100% dostępności. Bez karty kredytowej.

bullet_checkedNie wymaga karty kredytowej ani tworzenia kontaBrak ograniczeń. 100% dostępności. Bez karty kredytowej.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Otrzymaj swoją Konsultację Bez Zobowiązań
Wypełnij poniższy formularz lub wyślij e-mail na sales@ironsoftware.com
Twoje dane zawsze będą utrzymywane w tajemnicy.
Zaufane przez miliony inżynierów na całym świecie
Logotypy klientów Iron Software
Otrzymaj swój darmowy Klucz Próbny na 30 dni natychmiast.
Nie wymaga karty kredytowej ani tworzenia konta