Questa è la parola chiave C # in azione - non sta facendo nulla di speciale con l' www
oggetto, piuttosto significa qualcosa di speciale per il metodo in cui è contenuta. In particolare questa parola chiave può essere utilizzata solo in un metodo che restituisce un IEnumerable
(o IEnumerator
) e viene utilizzata per indicare quale oggetto verrà "restituito" dall'enumeratore quando viene chiamato MoveNext .
Funziona perché il compilatore converte l'intero metodo in una classe separata che implementa IEnumerable
(o IEnumerator
) usando una macchina a stati - il risultato netto è che il corpo del metodo stesso non viene eseguito fino a quando qualcuno non viene enumerato attraverso il valore restituito. Funzionerà con qualsiasi tipo, non c'è assolutamente nulla di speciale WWW
, piuttosto è il metodo di contenimento che è speciale.
Dai un'occhiata a Dietro le quinte della parola chiave yield di C # per avere qualche informazione in più sul tipo di codice generato dal compilatore C #, o semplicemente sperimenta e ispeziona il codice tu stesso usando qualcosa come IL Spy
Aggiornamento: per chiarire
- Quando Unity chiama una coroutine che contiene
yield return
un'istruzione tutto ciò che accade è che viene restituito un enumeratore - nessuno del corpo del metodo viene eseguito a questo punto
- Per ottenere il corpo del metodo da eseguire, Unity deve chiamare
MoveNext
l'iteratore per ottenere il primo valore nella sequenza. Questo fa sì che il metodo venga eseguito fino alla prima yeild return
istruzione, a quel punto il chiamante riprende (e presumibilmente Unity continua a rendere il resto del frame)
- A quanto ho capito, Unity normalmente continua a chiamare il
MoveNext
metodo sull'iteratore una volta per ogni fotogramma successivo, facendo sì che il metodo venga eseguito nuovamente fino yield return
all'istruzione successiva una volta per ogni fotogramma, fino a raggiungere la fine del metodo o yield break
un'istruzione (che indica la fine della sequenza)
L'unico bit speciale qui (e in un paio di altri casi ) è che Unity non fa avanzare questo particolare iteratore al fotogramma successivo, invece fa avanzare l'iteratore (facendo continuare l'esecuzione del metodo) al termine del download. Sebbene sembra esserci una classe YieldInstruction di base che presumibilmente contiene un meccanismo generico per segnalare a Unity quando un iteratore dovrebbe essere avanzato, la WWW
classe non sembra ereditare da questa classe, quindi posso solo supporre che ci sia un caso speciale per questa classe nel motore Unity.
Giusto per essere chiari: la yield
parola chiave non fa nulla di speciale per la WWW
classe, piuttosto è la gestione speciale che Unity dà ai membri dell'enumerazione restituita che causa questo comportamento.
Aggiorna il secondo: per quanto riguarda il meccanismo che WWW
utilizza per scaricare le pagine Web in modo asincrono, probabilmente utilizza il metodo HttpWebRequest.BeginGetResponse che utilizzerà internamente IO asincrono o in alternativa potrebbe utilizzare i thread (creando un thread dedicato o utilizzando un pool di thread).
yield return
per operazioni asincrone è un hack. In un "vero" programma C #, useresti aTask
per questo. Probabilmente Unity non li utilizza perché è stato creato prima di .Net 4.0, quando èTask
stato introdotto.