Condividi tramite


Errori e avvisi associati a parametri per riferimento, variabili e valori restituiti

Quando si utilizzano variabili di riferimento, è possibile che vengano generati gli errori seguenti:

  • CS0192: un campo readonly non può essere usato come valore ref o out (tranne che in un costruttore).
  • CS0199: un campo static readonly non può essere usato come valore ref o out (tranne che in un costruttore statico).
  • CS0206: una proprietà o un indicizzatore che non restituisce ref non può essere usato come valore out o ref.
  • CS0631: ref e out non sono validi in questo contesto.
  • CS0767: non è possibile ereditare l'interfaccia con i parametri di tipo specificati perché in tal caso il metodo conterrebbe overload diversi solo per ref e out.
  • CS1510: un valore ref o out deve essere una variabile assegnabile.
  • CS1605: non è possibile usare una variabile come valore ref o out perché è di sola lettura.
  • CS1623: gli iteratori non possono avere i parametri ref, in o out.
  • CS1649: i membri di un campo readonly non possono essere usati come valore ref o out (tranne che in un costruttore).
  • CS1651: i campi di un campo static readonly non possono essere usati come valore ref o out (tranne che in un costruttore statico).
  • CS1655: non è possibile usare campi di tipo come valore ref o out.
  • CS1657: non è possibile usare una variabile come valore ref o out.
  • CS1741: un parametro ref o out non può avere un valore predefinito.
  • CS1939: non è possibile passare la variabile di intervallo come parametro out o ref.
  • CS1988: i metodi asincroni non possono avere i parametri ref, in o out.
  • CS7084: un evento Windows Runtime non può essere passato come parametro out o ref.
  • CS8196: nello stesso elenco di argomenti non è consentito il riferimento a una variabile out tipizzata in modo implicito.
  • CS8325: non è possibile usare 'await' in un'espressione contenente un operatore condizionale ref.
  • CS8326: entrambi i valori dell'operatore condizionale devono essere valori ref, altrimenti nessuno dei due può esserlo.
  • CS8327: l'espressione deve essere di tipo corretto per essere uguale al valore ref alternativo.
  • CS8329: non è possibile usare una variabile come valore ref o out perché è una variabile readonly.
  • CS8330: i membri della variabile non possono essere usati come valore ref o out perché è una variabile readonly.
  • CS8331: non è possibile assegnarla a una variabile o usarla come valore di destra di un'assegnazione ref perché è una variabile readonly.
  • CS8332: non è possibile assegnarla a un membro della variabile o usarla come valore di destra di un'assegnazione ref perché è una variabile readonly.
  • CS8337: il primo parametro di un metodo di estensione 'ref' deve essere un tipo valore o un tipo generico vincolato a struct.
  • CS8338: il primo parametro 'in' o 'ref readonly' del metodo di estensione deve essere un tipo valore concreto (non generico).
  • CS8373: il valore di sinistra di un'assegnazione ref deve essere una variabile ref.
  • CS8388: non è possibile dichiarare una variabile out come variabile locale ref.
  • CS8977: non è possibile usare 'ref', 'in' o 'out' nella firma di un metodo con l'attributo 'UnmanagedCallersOnly'.
  • CS8986: Il modificatore 'scoped' del parametro non corrisponde alla destinazione.
  • CS8987: il modificatore di parametro con ambito non corrisponde al membro sottoposto a override o implementato.
  • CS9061: Il modificatore "con ambito definito" non può essere usato con discard.
  • CS9062: i tipi e gli alias non possono essere denominati 'scoped'.
  • CS9063: UnscopedRefAttribute non può essere applicato a questo parametro perché è senza ambito per impostazione predefinita.
  • CS9065: non usare 'System.Runtime.CompilerServices.ScopedRefAttribute'. Usare invece la parola chiave "scoped".
  • CS9066: UnscopedRefAttribute non può essere applicato ai parametri con un modificatore con ambito.
  • CS9072: una variabile di decostruzione non può essere dichiarata come variabile locale ref.
  • CS9101: UnscopedRefAttribute può essere applicato solo ai metodi e alle proprietà dell'istanza dell'interfaccia virtuale o struct e non può essere applicato a costruttori o membri solo init.
  • CS9102: UnscopedRefAttribute non può essere applicato a un'implementazione dell'interfaccia perché il membro implementato non ha questo attributo.
  • CS9104: una risorsa di istruzione using di tipo non può essere usata in metodi asincroni o espressioni lambda asincrone.
  • CS9190: il modificatore readonly deve essere specificato dopo ref.
  • CS9199: un parametro ref readonly non può avere l'attributo Out.

Gli avvisi seguenti vengono generati quando le variabili di riferimento vengono usate in modo non corretto:

  • CS9073: Il modificatore 'scoped' del parametro non corrisponde alla destinazione.
  • CS9074: Il modificatore 'scoped' del parametro non corrisponde al membro sottoposto a override o implementato.
  • CS9191: il modificatore ref per l'argomento corrispondente al parametro in equivale a in. In alternativa, provare a usare in.
  • CS9192: l'argomento deve essere passato con la parola chiave ref o in.
  • CS9193: l'argomento deve essere una variabile perché viene passato a un parametro ref readonly.
  • CS9195: l'argomento deve essere passato con la parola chiave in.
  • CS9196: il modificatore del tipo di riferimento del parametro non corrisponde al parametro corrispondente nel membro sottoposto a override o implementato.
  • CS9197: il modificatore del tipo di riferimento del parametro non corrisponde al parametro corrispondente nel membro nascosto.
  • CS9198: il modificatore del tipo di riferimento del parametro non corrisponde al parametro corrispondente nella destinazione.
  • CS9200: viene specificato un valore predefinito per il parametro ref readonly, ma ref readonly deve essere usato solo per i riferimenti. Provare a dichiarare il parametro come in.
  • CS9201: il valore ref deve essere assegnato al campo ref prima dell'uso.
  • CS9265: il campo non viene mai assegnato a riferimento e avrà sempre il valore predefinito (riferimento Null)

Questi errori e avvisi seguono questi temi:

Questo articolo usa il termine variabile di riferimento come termine generale per un parametro dichiarato con uno dei modificatori in, ref readonly, ref o out o una variabile locale ref, un campo ref in un oggetto ref struct o un valore restituito ref. Una variabile di riferimento fa riferimento a un'altra variabile, denominata referente.

Sintassi non corretta

Questi errori indicano che si sta usando una sintassi non corretta relativa alle variabili di riferimento:

  • CS8373: il valore di sinistra di un'assegnazione ref deve essere una variabile ref.
  • CS8388: non è possibile dichiarare una variabile out come variabile locale ref.
  • CS9190: il modificatore readonly deve essere specificato dopo ref.

Per correggere questi errori:

  • Verificare che l'operando sinistro di un = ref operatore sia una variabile di riferimento anziché un'espressione di valore o locale non di riferimento. L'assegnazione di riferimento richiede che entrambi i lati siano variabili di riferimento che possono creare un alias nella stessa posizione di archiviazione (CS8373).
  • Quando si dichiarano parametri di riferimento, scrivere il modificatore come ref readonly anziché readonly ref. La specifica del linguaggio C# richiede che la ref parola chiave precede il readonly modificatore nelle dichiarazioni di parametri per mantenere una sintassi coerente in tutti i tipi di parametri di riferimento (CS9190).
  • Usare la ref parola chiave anziché out quando si dichiarano variabili di riferimento locali. out è esclusivamente un modificatore di parametri che indica che un metodo deve assegnare un valore prima della restituzione, mentre ref è la parola chiave appropriata per la creazione di variabili locali che aliasno altre posizioni di archiviazione (CS8388). Per altre informazioni sulle variabili di riferimento e sui relativi requisiti di sintassi, vedere Variabili di riferimento e Specifica del linguaggio C#.

Restrizioni delle variabili di riferimento

Gli errori seguenti indicano che non è possibile usare una variabile di riferimento quando ne esiste una:

  • CS0631: ref e out non sono validi in questo contesto.
  • CS0767: non è possibile ereditare l'interfaccia con i parametri di tipo specificati perché in tal caso il metodo conterrebbe overload diversi solo per ref e out.
  • CS1623: gli iteratori non possono avere i parametri ref, in o out.
  • CS1741: un parametro ref o out non può avere un valore predefinito.
  • CS1939: non è possibile passare la variabile di intervallo come parametro out o ref.
  • CS1988: i metodi asincroni non possono avere i parametri ref, in o out.
  • CS7084: un evento Windows Runtime non può essere passato come parametro out o ref.
  • CS8196: nello stesso elenco di argomenti non è consentito il riferimento a una variabile out tipizzata in modo implicito.
  • CS8325: non è possibile usare 'await' in un'espressione contenente un operatore condizionale ref.
  • CS8326: entrambi i valori dell'operatore condizionale devono essere valori ref, altrimenti nessuno dei due può esserlo.
  • CS8327: l'espressione deve essere di tipo corretto per essere uguale al valore ref alternativo.
  • CS8337: il primo parametro di un metodo di estensione 'ref' deve essere un tipo valore o un tipo generico vincolato a struct.
  • CS8338: il primo parametro 'in' o 'ref readonly' del metodo di estensione deve essere un tipo valore concreto (non generico).
  • CS8977: non è possibile usare 'ref', 'in' o 'out' nella firma di un metodo con l'attributo 'UnmanagedCallersOnly'.
  • CS9072: una variabile di decostruzione non può essere dichiarata come variabile locale ref.
  • CS9104: una risorsa di istruzione using di tipo non può essere usata in metodi asincroni o espressioni lambda asincrone.
  • CS9199: un parametro ref readonly non può avere l'attributo Out.

Gli avvisi seguenti indicano che una variabile di riferimento non deve essere usata e potrebbe non essere sicura:

  • CS9196: il modificatore del tipo di riferimento del parametro non corrisponde al parametro corrispondente nel membro sottoposto a override o implementato.
  • CS9197: il modificatore del tipo di riferimento del parametro non corrisponde al parametro corrispondente nel membro nascosto.
  • CS9198: il modificatore del tipo di riferimento del parametro non corrisponde al parametro corrispondente nella destinazione.
  • CS9200: viene specificato un valore predefinito per il parametro ref readonly, ma ref readonly deve essere usato solo per i riferimenti. Provare a dichiarare il parametro come in.
  • CS9201: il valore ref deve essere assegnato al campo ref prima dell'uso.
  • CS9265: il campo non viene mai assegnato a riferimento e avrà sempre il valore predefinito (riferimento Null)

Per correggere questi errori:

  • Rimuovere i parametri di riferimento dagli indicizzatori. Gli indicizzatori sono progettati per fornire una sintassi di accesso simile a una matrice e il compilatore non può garantire il rilevamento della durata sicura per i riferimenti passati tramite le funzioni di accesso dell'indicizzatore (CS0631, CS1623).
  • Rimuovere i parametri di riferimento dai metodi dell'iteratore. Gli iteratori eseguono il codice in modo differito attraverso più chiamate utilizzando macchine a stati e il compilatore non può garantire che le variabili di riferimento rimangano valide nei punti di confine del rendimento dove l'esecuzione viene sospesa e ripresa (CS1623).
  • Rimuovere i parametri di riferimento dai metodi asincroni. I metodi asincroni potrebbero sospendere l'esecuzione nei punti di attesa e riprendere su thread diversi, rendendo impossibile garantire che le variabili di riferimento rimangano valide e accessibili durante l'esecuzione del metodo (CS1988).
  • Evitare di usare espressioni await all'interno di espressioni condizionali ref. L'operazione await potrebbe sospendere l'esecuzione e invalidare i riferimenti selezionati dall'operatore condizionale, causando un potenziale uso di riferimenti invalidati quando l'esecuzione riprende (CS8325).
  • Assicurarsi che entrambi i rami di un operatore condizionale ref restituiscano riferimenti o nessuno restituisca un riferimento e quando entrambi sono riferimenti devono essere dello stesso tipo. L'operatore condizionale deve produrre un tipo di risultato coerente che può essere usato in modo sicuro dal codice chiamante indipendentemente dal ramo selezionato (CS8326, CS8327).
  • Rimuovere i valori predefiniti dai ref parametri e out . I parametri di riferimento devono sempre essere forniti nel sito di chiamata per stabilire la relazione di aliasing necessaria tra il parametro e una variabile esistente, rendendo i valori predefiniti semanticamente senza significato (CS1741).
  • Evitare di dichiarare una variabile tipizzata in modo implicito out in un elenco di argomenti che fa riferimento anche alla stessa variabile. Il compilatore deve dedurre il tipo della variabile dalla firma del metodo durante la convalida simultanea dell'uso di tale variabile all'interno della stessa espressione, creando una dipendenza circolare (CS8196).
  • Non passare variabili dell'intervallo di query LINQ come parametri di riferimento. Le variabili di intervallo sono variabili di iterazione generate dal compilatore la cui durata è gestita dal modello di esecuzione delle query e non hanno percorsi di memoria stabili a cui è possibile fare riferimento in modo sicuro (CS1939).
  • Usare variabili di valore regolari anziché variabili locali di riferimento durante la decostruzione di oggetti. La decostruzione crea nuove variabili per ricevere i valori deconstruiti e le variabili di riferimento tentano di eseguire l'alias di questi valori temporanei anziché archiviarli in modo indipendente (CS9072).
  • Evitare di implementare più interfacce in cui i metodi differiscono solo per i modificatori ref e out sui parametri. La specifica del linguaggio C# li considera come firme distinte, ma non offre un modo per disambiguare quale implementazione chiamare, perché sia ref che out condividono la stessa sintassi chiamante ai limiti di implementazione (CS0767).
  • Rimuovere i parametri di riferimento dai metodi decorati con System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute. Questi metodi sono chiamabili da codice non gestito che non riconosce le regole di sicurezza di riferimento di C#e non può garantire una corretta gestione della durata delle variabili a cui si fa riferimento attraverso il limite gestito/non gestito (CS8977).
  • Usare il modificatore ref sui primi parametri del metodo di estensione solo per i tipi valore o per i tipi generici vincolati a tipi valore. I tipi di riferimento sono già passati per riferimento a livello CLR e l'aggiunta ref crea un riferimento a un riferimento, mentre le estensioni del tipo valore con ref abilitano la mutazione dell'istanza estesa (CS8337, CS8338).
  • Non passare gli eventi di Windows Runtime come parametri di riferimento. Questi eventi seguono il sistema dei tipi di Windows Runtime, che ha una semantica di durata e threading diversa rispetto ai riferimenti .NET e non supporta il comportamento di aliasing richiesto dai parametri di riferimento C# (CS7084).
  • Rimuovere l'oggetto System.Runtime.InteropServices.OutAttribute dai ref readonly parametri. Questo attributo è progettato per il marshalling della semantica negli scenari di chiamata piattaforma in cui la direzione del parametro è solo in uscita, il che è in conflitto con la garanzia che il parametro faccia riferimento a dati esistenti che non verranno riassegnati (ref readonly).
  • Assicurarsi che tutti i ref campi di un tipo vengano assegnati negli inizializzatori di campo o in tutti i percorsi di codice del costruttore prima del completamento del costruttore. I campi ref non inizializzati contengono riferimenti non validi che potrebbero causare un danneggiamento della memoria se si accede (CS9201, CS9265).
  • Abbina i modificatori del tipo di riferimento (ref, in, out, ref readonly) tra un metodo e il metodo di base sottoposto a override o il metodo di interfaccia implementato. Il modificatore di riferimento fa parte del contratto della signature del metodo che i tipi derivati devono rispettare per mantenere la sostituibilità e le aspettative dell'utente chiamante (CS9196, CS9197, CS9198).
  • Dichiarare i parametri come in anziché ref readonly quando si specificano valori predefiniti. ref readonly è progettato per scenari in cui il chiamante passa un riferimento a una variabile esistente, mentre in i parametri possono accettare sia riferimenti che copie temporanee di valori, rendendo significativi i valori predefiniti (CS9200).

Per altre informazioni sulla posizione in cui sono consentite le variabili di riferimento, vedere Parametri del metodo, Iteratori, Modelli di programmazione asincroni e Specifica del linguaggio C#.

Restrizioni di unscoped ref

Il qualificatore unscoped per i parametri ref non è consentito in alcune posizioni:

  • CS9101: UnscopedRefAttribute può essere applicato solo ai metodi e alle proprietà dell'interfaccia virtuale o all'istanza di struct e non può essere applicato ai costruttori o ai membri solo init.
  • CS9102: UnscopedRefAttribute non può essere applicato a un'implementazione dell'interfaccia perché il membro implementato non ha questo attributo.

Per correggere questi errori:

  • Rimuovere il unscoped modificatore o l'attributo System.Diagnostics.CodeAnalysis.UnscopedRefAttribute dai costruttori di struct e dai membri init-only. Questi membri hanno una semantica di inizializzazione speciale in cui il compilatore deve garantire che tutti i riferimenti non superino la fase di inizializzazione, e consentire riferimenti non delimitati violerebbe la garanzia che l'inizializzazione venga completata prima che la struttura diventi completamente accessibile (CS9101).
  • Rimuovere il unscoped modificatore dai metodi di implementazione dell'interfaccia quando il metodo di interfaccia corrispondente non lo ha. La caratteristica non specificata influisce sul contratto del metodo per quanto riguarda le garanzie di durata dei riferimenti, e le implementazioni dei metodi devono mantenere lo stesso contratto dell'interfaccia che stanno implementando per garantire che i chiamanti possano basarsi su un comportamento di durata coerente, indipendentemente dall'implementazione richiamata (CS9102).

Per altre informazioni sui riferimenti con e senza ambito, vedere Parametri del metodo e la specifica delle funzionalità miglioramenti delle strutture a basso livello.

Le variabili di riferimento richiedono un referente

È necessario fornire una variabile come argomento a un parametro per riferimento, a un valore restituito di riferimento o a un'assegnazione della variabile locale ref:

  • CS0206: una proprietà o un indicizzatore che non restituisce ref non può essere usato come valore out o ref.
  • CS1510: un valore ref o out deve essere una variabile assegnabile.

Warnings (Avvisi):

  • CS9191: il modificatore ref per l'argomento corrispondente al parametro in equivale a in. In alternativa, provare a usare in.
  • CS9192: l'argomento deve essere passato con la parola chiave ref o in.
  • CS9193: l'argomento deve essere una variabile perché viene passato a un parametro ref readonly.
  • CS9195: l'argomento deve essere passato con la parola chiave in.

Per correggere questi errori:

  • Archiviare il risultato di un accesso a una proprietà o a un indicizzatore in una variabile locale prima di passarlo come parametro di riferimento. Le proprietà e gli indicizzatori sono metodi che restituiscono valori anziché fornire l'accesso diretto ai percorsi di archiviazione e i parametri di riferimento richiedono una variabile effettiva con una posizione di memoria stabile che può essere aliasata (CS0206, CS1510).
  • Usare il in modificatore invece di ref quando si passano argomenti ai in parametri. Anche se ref tecnicamente funziona a causa della compatibilità con le versioni precedenti, il in modificatore esprime più chiaramente la finalità che l'argomento è di sola lettura e può essere passato in modo più efficiente come riferimento senza copiare (CS9191, CS9195).
  • Aggiungere il modificatore di riferimento appropriato (ref, ino ref readonly) quando si passano argomenti ai parametri che prevedono riferimenti. L'omissione del modificatore potrebbe causare la creazione di una copia temporanea del valore, che è inefficiente e può causare un comportamento imprevisto se il codice chiamante prevede che le modifiche vengano riflesse nella variabile originale (CS9192, CS9193).

Per altre informazioni sui parametri di riferimento e sul passaggio di variabili per riferimento, vedere Parametri del metodo, parola chiave ref e specifica del linguaggio C#.

Le variabili di riferimento scrivibili richiedono un referente scrivibile

Una variabile di riferimento scrivibile richiede che anche il referente sia scrivibile. Gli errori seguenti indicano che la variabile non è scrivibile:

  • CS0192: un campo readonly non può essere usato come valore ref o out (tranne che in un costruttore).
  • CS0199: un campo static readonly non può essere usato come valore ref o out (tranne che in un costruttore statico).
  • CS1605: non è possibile usare una variabile come valore ref o out perché è di sola lettura.
  • CS1649: i membri di un campo readonly non possono essere usati come valore ref o out (tranne che in un costruttore).
  • CS1651: i campi di un campo static readonly non possono essere usati come valore ref o out (tranne che in un costruttore statico).
  • CS1655: non è possibile usare campi di tipo come valore ref o out.
  • CS1657: non è possibile usare una variabile come valore ref o out.
  • CS8329: non è possibile usare una variabile come valore ref o out perché è una variabile readonly.
  • CS8330: i membri della variabile non possono essere usati come valore ref o out perché è una variabile readonly.
  • CS8331: non è possibile assegnarla a una variabile o usarla come valore di destra di un'assegnazione ref perché è una variabile readonly.
  • CS8332: non è possibile assegnarla a un membro della variabile o usarla come valore di destra di un'assegnazione ref perché è una variabile readonly.

Per correggere questi errori:

  • Copiare il valore da un campo di sola lettura in una variabile locale e passare la variabile locale come parametro ref o out. I campi readonly sono immutabili dopo l'inizializzazione (eccetto all'interno dei costruttori) e consentire riferimenti scrivibili a tali campi violerebbe la garanzia di immutabilità fornita dal readonly stesso (CS0192, CS0199, CS1649, CS1651).
  • Usare ref readonly o in parametri anziché ref o out quando è necessario passare variabili readonly, variabili di iterazione o altri valori non scrivibili per riferimento. Questi modificatori indicano che il metodo leggerà solo il valore a cui si fa riferimento senza tentare di modificarlo. Allineato ai vincoli di immutabilità della variabile originale (CS1605, CS1655, CS1657, CS8329).
  • Copiare i membri delle variabili readonly nelle variabili locali prima di passarli come riferimenti scrivibili. Anche se il membro stesso potrebbe non essere dichiarato come readonly, è accessibile tramite un percorso readonly (tramite un campo, in un parametro o ref readonly un locale readonly) e il compilatore applica la transitività di readonly-ness per impedire la mutazione indiretta dei dati readonly (CS8330, CS8332).
  • Evitare assegnazioni di riferimento scrivibili alle variabili readonly, alle variabili di iterazione foreach, all'uso di risorse di istruzione o alle variabili di istruzione fisse. Queste variabili hanno una semantica di durata speciale gestita dal compilatore. La variabile viene automaticamente finalizzata o eliminata alla fine del relativo ambito. I riferimenti esterni creano riferimenti pendenti dopo l'eliminazione (CS8331).

Per altre informazioni sulla semantica di sola lettura e sui parametri di riferimento, vedere parola chiave readonly, nel modificatore di parametri, ref readonly e nella specifica del linguaggio C#.