Condividi tramite


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 facoltativamente yield break) non può usare anche un'istruzione return 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 per ref. È 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 clausola catch o finally.
  • Non è possibile yield return da un blocco try con una clausola catch.
  • Non è possibile yield return da un blocco unsafe. Il contesto per un iteratore crea un blocco safe nidificato all'interno di un blocco unsafe 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.