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.
  • CS8166: non è possibile restituire un parametro per riferimento perché non è un parametro ref.
  • CS8167: non è possibile restituire per riferimento un membro del parametro perché non è un parametro ref o out.
  • CS8168: non è possibile restituire una variabile locale per riferimento perché non è una variabile locale ref.
  • CS8169: non è possibile restituire un membro della variabile locale per riferimento perché non è una variabile locale 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).
  • CS8351: i rami di un operatore condizionale ref non possono fare riferimento a variabili con ambiti di dichiarazione incompatibili.
  • CS8373: il valore di sinistra di un'assegnazione ref deve essere una variabile ref.
  • CS8374: non è possibile assegnare un valore ref perché l'origine ha un ambito di escape più ristretto rispetto a quello di destinazione.
  • 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'.
  • CS9072: una variabile di decostruzione non può essere dichiarata come variabile locale ref.
  • CS9077: non è possibile restituire un parametro per riferimento tramite un parametro ref. Può essere restituito solo in un'istruzione return.
  • CS9078: non è possibile restituire per riferimento un membro del parametro tramite un parametro ref. Può essere restituito solo in un'istruzione return.
  • CS9079: non è possibile assegnare un valore ref perché l'origine può eseguire l'escape solo del metodo corrente tramite un'istruzione return.
  • CS9096: non è possibile assegnare un valore ref perché l'origine ha un ambito di escape del valore più ampio rispetto a quello di destinazione consentendo l'assegnazione tramite l'origine di valori con ambiti di escape più ristretti rispetto a quelli di destinazione.
  • 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:

  • CS9085: assegna alla variabile un valore ref ma la destinazione ha un ambito di escape più ristretto rispetto a quello di origine.
  • CS9086: i rami dell'operatore condizionale ref fanno riferimento a variabili con ambiti di dichiarazione incompatibili.
  • CS9087: restituisce un parametro per riferimento, ma non è un parametro ref.
  • CS9089: restituisce per riferimento un membro del parametro che non è un parametro ref o out.
  • CS9091: restituisce una variabile locale per riferimento, ma non è una variabile locale ref.
  • CS9092: restituisce un membro della variabile locale per riferimento, ma non è una variabile locale ref.
  • CS9093: assegna un valore ref ma l'origine può eseguire l'escape solo del metodo corrente tramite un'istruzione return.
  • CS9094: restituisce un parametro per riferimento tramite un parametro ref, ma può essere restituito in modo sicuro solo in un'istruzione return.
  • CS9095: restituisce per riferimento un membro del parametro tramite un parametro ref, ma può essere restituito in modo sicuro solo in un'istruzione return.
  • CS9097: assegna un valore ref ma l'origine ha un ambito di escape del valore più ampio rispetto a quello di destinazione consentendo l'assegnazione tramite la destinazione di valori con ambiti di escape più ristretti rispetto a quelli di origine.
  • 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.

È possibile correggere l'errore con una delle modifiche seguenti:

  • L'operando sinistro di un operatore = ref deve essere una variabile di riferimento. Per altre informazioni sulla sintassi corretta, vedere Variabili di riferimento.
  • Il modificatore di parametro ref readonly deve essere in questo ordine. readonly ref non è un modificatore di parametro valido. Cambiare l'ordine delle parole.
  • Una variabile locale non può essere dichiarata come out. Per dichiarare una variabile di riferimento locale, usare ref.

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 l'errore, rimuovere la variabile di riferimento dove non è consentita:

  • Rimuovere i parametri in, ref e out da indicizzatori, iteratori e metodi asincroni.
  • Rimuovere le espressioni condizionali ref (? :) che includono un operatore await.
  • Rimuovere il modificatore ref dal primo parametro di un metodo di estensione se il tipo non è un tipo valore o un tipo generico vincolato come tipo valore.
  • Entrambe o nessuna delle due [espressioni dell'operatore condizionale] devono essere variabili ref. Rimuovere ref da un'espressione o aggiungerla all'altra. Se si tratta di un'espressione condizionale ref, entrambe le espressioni devono essere dello stesso tipo.
  • I parametri ref e out non possono avere valori predefiniti. Rimuovere il modificatore ref o out oppure rimuovere il valore predefinito.
  • Una dichiarazione di variabile out tipizzata in modo implicito non può essere presente anche altrove nello stesso elenco di argomenti.
  • Non è possibile inserire variabili di riferimento in un'istruzione using nelle espressioni lambda dei metodi async.
  • La variabile di intervallo in un'espressione di query LINQ non può essere passata per riferimento.
  • Non è possibile decostruire un oggetto in variabili di riferimento. Sostituire le variabili di riferimento con variabili di valore.
  • Non è possibile implementare più interfacce in cui gli overload dei metodi differiscono solo per ref e out. Ad esempio, un'interfaccia dichiara void M(ref int i) e un'altra interfaccia dichiara void M(out int i). Una classe non può implementare entrambe le interfacce perché i metodi non sono distinguibili. È possibile implementare solo una di queste interfacce.
  • I metodi con l'attributo System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute non possono usare parametri per riferimento.
  • Un evento Windows Runtime non può essere passato come variabile di riferimento.
  • Non è possibile applicare l'attributo System.Runtime.InteropServices.OutAttribute a un parametro ref readonly nell'API di comunicazione remota.
  • Inizializzare un ref campo nel costruttore o come inizializzatore di campo.

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'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.

È necessario rimuovere il modificatore unscoped dalla dichiarazione del parametro che ha causato l'errore.

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.

Il compilatore genera questi errori quando si usa un'espressione che calcola un valore in cui deve essere usata una variabile. È necessario archiviare il risultato di tale espressione in una variabile per usarla. Ad esempio, le proprietà e gli indicizzatori restituiscono valori, non variabili. È necessario archiviare il risultato in una variabile e passare un riferimento a tale variabile.

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.

Esempi di variabili non scrivibili sono:

  • Campi readonly, sia campi di istanza che statici.
  • Membri dei campi readonly.
  • Variabile this.
  • Variabile di iterazione foreach.
  • Variabile using o variabile fixed.

È necessario copiare il valore e passare un riferimento alla copia.

Violazioni di sicurezza delle variabili ref

Il compilatore tiene traccia del contesto sicuro dei referenti e delle variabili di riferimento. Il compilatore genera errori o avvisi nel codice non gestito quando una variabile di riferimento fa riferimento a una variabile referente che non è più valida. Il referente deve avere un contesto sicuro ampio almeno quanto il contesto sicuro di riferimento della variabile di riferimento. Se si violano questi controlli di sicurezza, la variabile di riferimento accede alla memoria casuale anziché alla variabile referente.

  • CS8166: non è possibile restituire un parametro per riferimento perché non è un parametro ref.
  • CS8167: non è possibile restituire per riferimento un membro del parametro perché non è un parametro ref o out.
  • CS8168: non è possibile restituire una variabile locale per riferimento perché non è una variabile locale ref.
  • CS8169: non è possibile restituire un membro della variabile locale per riferimento perché non è una variabile locale ref.
  • CS8345: un campo o una proprietà implementata automaticamente non può essere di tipo a meno che non sia un membro di istanza di un valore ref struct.
  • CS8351: i rami di un operatore condizionale ref non possono fare riferimento a variabili con ambiti di dichiarazione incompatibili.
  • CS8374: non è possibile assegnare un valore ref perché l'origine ha un ambito di escape più ristretto rispetto a quello di destinazione.
  • CS9077: non è possibile restituire un parametro per riferimento tramite un parametro ref. Può essere restituito solo in un'istruzione return.
  • CS9078: non è possibile restituire per riferimento un membro del parametro tramite un parametro ref. Può essere restituito solo in un'istruzione return.
  • CS9079: non è possibile assegnare un valore ref dall'origine alla destinazione perché l'origine può eseguire l'escape solo del metodo corrente tramite un'istruzione return.
  • CS9096: non è possibile assegnare un valore ref dall'origine alla destinazione perché l'origine ha un ambito di escape del valore più ampio rispetto a quello di destinazione consentendo l'assegnazione tramite la destinazione di valori con ambiti di escape più ristretti rispetto a quelli di origine.

Warnings (Avvisi):

  • CS9085: assegna un valore ref dall'origine alla destinazione ma l'origine ha un ambito di escape più ristretto rispetto a quello di destinazione.
  • CS9086: i rami dell'operatore condizionale ref fanno riferimento a variabili con ambiti di dichiarazione incompatibili.
  • CS9087: restituisce un parametro per riferimento, ma non è un parametro ref.
  • CS9089: restituisce per riferimento un membro del parametro che non è un parametro ref o out.
  • CS9091: restituisce una variabile locale per riferimento, ma non è una variabile locale ref.
  • CS9092: restituisce un membro della variabile locale per riferimento, ma non è una variabile locale ref.
  • CS9093: assegna un valore ref dall'origine alla destinazione ma l'origine può eseguire l'escape solo del metodo corrente tramite un'istruzione return.
  • CS9094: restituisce un parametro per riferimento tramite un parametro ref, ma può essere restituito in modo sicuro solo in un'istruzione return.
  • CS9095: restituisce per riferimento un membro del parametro tramite un parametro ref, ma può essere restituito in modo sicuro solo in un'istruzione return.
  • CS9097: assegna un valore ref dall'origine alla destinazione ma l'origine ha un ambito di escape del valore più ampio rispetto a quello di destinazione consentendo l'assegnazione tramite la destinazione di valori con ambiti di escape più ristretti rispetto a quelli di origine.

Il compilatore usa l'analisi statica per determinare se il referente è valido in tutti i punti in cui è possibile usare la variabile di riferimento. È necessario effettuare il refactoring del codice in modo che il referente rimanga valido in tutte le posizioni in cui la variabile di riferimento potrebbe farvi riferimento. Per informazioni dettagliate sulle regole per la sicurezza dei riferimenti, vedere lo standard C# nei contesti sicuri di riferimento.