Jest to słowo kluczowe C # w działaniu - nie robi nic specjalnego z www
obiektem, a raczej oznacza coś specjalnego dla metody w nim zawartej. W szczególności tego słowa kluczowego można użyć tylko w metodzie, która zwraca IEnumerable
(lub IEnumerator
) i jest używana wskazujący, który obiekt zostanie „zwrócony” przez moduł wyliczający, gdy zostanie wywołane MoveNext .
Działa, ponieważ kompilator konwertuje całą metodę na osobną klasę, która implementuje IEnumerable
(lub IEnumerator
) za pomocą automatu stanów - wynik netto jest taki, że ciało samej metody nie jest wykonywane, dopóki ktoś nie wyliczy wartości zwracanej. Działa to z każdym typem, nie ma w tym absolutnie nic specjalnego WWW
, a raczej metoda zawierająca, która jest wyjątkowa.
Rzuć okiem za kulisy słowa kluczowego wydajności C #, aby uzyskać więcej informacji na temat tego, jaki rodzaj kodu generuje kompilator C #, lub po prostu eksperymentuj i sprawdź kod samodzielnie, używając czegoś takiego jak IL Spy
Aktualizacja: w celu wyjaśnienia
- Gdy Unity wywołuje coroutine, która zawiera
yield return
instrukcję, dzieje się tak, że zwracany jest moduł wyliczający - w tym momencie nie jest wykonywana żadna treść metody
- Aby uzyskać treść metody do wykonania, Unity musi wywołać
MoveNext
iterator w celu uzyskania pierwszej wartości w sekwencji. Powoduje to, że metoda wykonuje się do pierwszej yeild return
instrukcji, w którym to momencie osoba dzwoniąca wznawia (i prawdopodobnie Unity renderuje resztę ramki)
- Jak rozumiem, Unity normalnie następnie wywołuje
MoveNext
metodę na iteratorze co każdą kolejną ramkę, powodując, że metoda wykonuje się ponownie aż do następnej yield return
instrukcji po każdej ramce, aż do osiągnięcia końca metody lub yield break
instrukcji (wskazując koniec sekwencji)
Jedynym specjalny bit tutaj (oraz w kilku z pozostałych przypadkach ) jest to, że Unity nie posuwa tej konkretnej iterator następną ramkę, zamiast tylko przesuwa iterator (powodując metodę, aby kontynuować wykonywanie) po zakończeniu pobierania. Chociaż wydaje się, że istnieje podstawowa klasa YieldInstruction, która prawdopodobnie zawiera ogólny mechanizm sygnalizowania Unity, kiedy iterator powinien być zaawansowany, WWW
klasa nie wydaje się dziedziczyć po tej klasie, więc mogę jedynie założyć, że istnieje specjalny przypadek ta klasa w silniku Unity.
Żeby było jasne - yield
słowo kluczowe nie robi nic specjalnego dla WWW
klasy, a raczej specjalną obsługę, jaką Unity zapewnia członkom zwróconego wyliczenia, co powoduje takie zachowanie.
Zaktualizuj drugi: Jeśli chodzi o mechanizm, który WWW
używa do asynchronicznego pobierania stron internetowych, prawdopodobnie używa albo metody HttpWebRequest.BeginGetResponse, która wewnętrznie użyje asynchronicznego We / Wy lub alternatywnie może użyć wątków (albo tworząc dedykowany wątek, albo używając puli wątków).
yield return
do operacji asynchronicznych to włamanie. W „prawdziwym” programie C # użyłbyśTask
do tego celu. Unity prawdopodobnie ich nie używa, ponieważ został stworzony przed .Net 4.0, kiedyTask
został wprowadzony.