Przejdź do treści stopki
Iron Academy Logo
Naucz się C#
Naucz się C#

Inne Kategorie

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

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 słowa 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 zrozumieniuiuiuiuie 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.

Understanding Yield In Csharp 1 related to Przygotowywanie prostego przykładu: Klasa Program i Static Void Main

Co dokładnie robi Yield 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 zrozumieniuiuiuiuia, 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.

Understanding Yield In Csharp 2 related to Tworzenie klasy PersonModel

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. Początkowo wartość zwracana to lista wypełniona trzema instancjami PersonModel: Tim Corey, Sue Storm i Jane Smith.

Understanding Yield In Csharp 3 related to Tworzenie klasy DataAccess z tradycyjnym zwróceniem listy

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.

Understanding Yield In Csharp 4 related to Tworzenie klasy DataAccess z tradycyjnym zwróceniem listy

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.

Understanding Yield In Csharp 5 related to Demonstracja użycia pamięci za pomocą List

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, 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.

Understanding Yield In Csharp 6 related to Debugowanie: Jak kompilator generuje kod dla Yield

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, dłączego 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 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);
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: Dłączego 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 zrozumieniuiuiuiuie 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.

Hero Worlddot related to Wprowadzenie do Yield w C# - Czym jest, jak go używać i kiedy jest przydatny
Hero Affiliate related to Wprowadzenie do Yield w C# - Czym jest, jak go używać i kiedy jest przydatny

Zarabiaj więcej, dzieląc się tym, co kochasz

Tworzysz treści dla deweloperów pracujących z .NET, C#, Java, Python, czy Node.js? Zamień swoją wiedzę specjalistyczną na dodatkowy dochód!

Zespol wsparcia Iron

Jestesmy online 24 godziny, 5 dni w tygodniu.
Czat
Email
Zadzwon do mnie