Errori e avvisi relativi all'istruzione yield return
e ai metodi iteratori
Esistono numerosi errori relativi all'istruzione yield return
e ai metodi iteratori:
- CS1622: impossibile restituire un valore da un iteratore. Usare l'istruzione yield return per restituire un valore o yield break per terminare l'iterazione.
- CS1624: Il corpo di 'accessor' non può essere un blocco iteratore perché 'type' non è un tipo interfaccia iteratore
- CS1625: Impossibile eseguire la produzione nel corpo di una clausola finally
- CS1626: Impossibile produrre un valore nel corpo di un blocco try con una clausola catch
- CS1627: Dopo yield return è prevista l'espressione
- CS1629: Gli iteratori non possono contenere codice unsafe
- CS1631: Impossibile produrre un valore nel corpo di una clausola catch
- CS1637: Gli iteratori non possono avere parametri unsafe o tipi yield
- CS4013: L'istanza del tipo non può essere usata all'interno di funzioni nidificate, espressioni di query, blocchi iteratori o metodi asincroni
- CS8154: Il corpo non può essere un blocco iteratore perché restituisce per riferimento
- CS8176: Gli iteratori non possono avere locali per riferimento
- CS9238: Impossibile usare 'yield return' in un blocco 'unsafe'
-
CS9239: L'operatore
&
non si può usare su parametri o variabili locali nei metodi iteratori.
Struttura di un metodo iteratore
Un metodo iteratore deve rispettare diverse regole in C#. Il compilatore genera gli errori seguenti quando il metodo iteratore viola una o più di queste regole:
- CS1622: Impossibile restituire un valore da un iteratore. Usare l'istruzione yield return per restituire un valore o yield break per terminare l'iterazione.
- CS1624: Il corpo di 'accessor' non può essere un blocco iteratore perché 'type' non è un tipo interfaccia iteratore
- CS1627: Dopo yield return è prevista l'espressione
- CS1637: Gli iteratori non possono avere parametri unsafe o tipi yield
- CS8154: Il corpo non può essere un blocco iteratore perché restituisce per riferimento
Il metodo iteratore deve seguire le regole seguenti:
- Un metodo iteratore (usando
yield return
e facoltativamenteyield break
) non può usare anche un'istruzionereturn
per restituire una sequenza. - Un metodo iteratore deve dichiarare un tipo di interfaccia iteratore come tipo restituito. I tipi di interfaccia iteratore sono: IEnumerable, IEnumerable<T>, IEnumerator, IEnumerator<T>.
- Un'istruzione
yield return
deve includere un'espressione da restituire come parte di una sequenza.yield return;
non è valido. - Un metodo iteratore non può usare tipi unsafe come parametri, ad esempio puntatori.
- Un metodo iteratore non può
yield return
tipi unsafe, ad esempio i puntatori. - Un metodo iteratore non può
yield return
perref
. È necessario restituire per valore.
Vincoli sui metodi iteratori
Il corpo di un metodo iteratore deve essere conforme ai vincoli relativi all'istruzione yield return
e al suo contesto. Il compilatore genera gli errori seguenti quando l'iteratore viola uno di questi vincoli:
- CS1625: Impossibile eseguire la produzione nel corpo di una clausola finally
- CS1626: Impossibile produrre un valore nel corpo di un blocco try con una clausola catch
- CS1631: Impossibile produrre un valore nel corpo di una clausola catch
- CS1629: Gli iteratori non possono contenere codice unsafe
- CS9238: Impossibile usare 'yield return' in un blocco 'unsafe'
-
CS9239: L'operatore
&
non si può usare su parametri o variabili locali nei metodi iteratori.
Questi errori indicano che il codice viola le regole di sicurezza, perché un iteratore restituisce un elemento e riprende per generare l'elemento successivo:
- Non è possibile
yield return
da una clausolacatch
ofinally
. - Non è possibile
yield return
da un bloccotry
con una clausola catch. - Non è possibile
yield return
da un bloccounsafe
. Il contesto per un iteratore crea un bloccosafe
nidificato all'interno di un bloccounsafe
di inclusione. - Non è possibile usare l'operatore
&
per accettare l'indirizzo di una variabile in un metodo iteratore.
Prima di C# 13, gli iteratori non possono contenere codice unsafe
(CS1629). A partire da C# 13, questo vincolo è stato allentato. Tutte le istruzioni yield return
devono trovarsi in un contesto safe, ma un metodo iteratore può contenere codice unsafe
.
sicurezza dei riferimenti nei metodi iteratori
I metodi iteratori presentano vincoli speciali per la sicurezza dei riferimenti. Queste regole sono meno stringenti in C# 13:
- CS4013: L'istanza del tipo non può essere usata all'interno di funzioni nidificate, espressioni di query, blocchi iteratori o metodi asincroni
- CS8176: Gli iteratori non possono avere locali per riferimento
Prima di C# 13, gli iteratori non potevano dichiarare variabili locali ref
. Non è stato possibile dichiarare alcuna variabile di un tipo ref struct
.
A partire da C# 13, i tipi ref struct
possono essere usati nei metodi iteratore, se non sono accessibili tramite l’istruzione yield return
. A partire da C# 13, i metodi iteratori possono dichiarare variabili locali ref
.