Risolvere gli avvisi correlati alle istruzioni using e dichiarazioni using

Questo articolo illustra gli errori del compilatore seguenti:

  • CS0245: I distruttori e object.Finalize non possono essere chiamati direttamente. Considerare di chiamare IDisposable.Dispose se disponibile.
  • CS0728: Possibile assegnazione errata a una variabile locale che è l'argomento di un'istruzione using o lock. La Dispose chiamata o lo sblocco verranno eseguiti sul valore originale della variabile locale.
  • CS1674: il tipo usato in un'istruzione using deve essere convertibile in modo implicito in 'System.IDisposable'.
  • CS8410: 'Il tipo usato in un'istruzione asincrona using deve essere convertibile in modo implicito in 'System.IAsyncDisposable' o implementare un metodo 'DisposeAsync' appropriato.
  • CS8417: Il tipo utilizzato in una dichiarazione using asincrona deve implementare 'System.IAsyncDisposable' o implementare un metodo 'DisposeAsync' adeguato. Ha voluto dire 'using' anziché 'await using'?
  • CS8418: Il tipo utilizzato in una dichiarazione using deve implementare 'System.IDisposable'. Intendevi "await using" invece di "using"?
  • CS8647: una variabile using non può essere usata direttamente all'interno di una sezione switch (prendere in considerazione l'uso di parentesi graffe).
  • CS8648: non goto è possibile passare a una posizione dopo una dichiarazione using.
  • CS8649: non goto è possibile passare a una posizione prima di una dichiarazione using all'interno dello stesso blocco.
  • CS9229: Non si possono inserire modificatori nelle dichiarazioni using.

Implementazione di IDisposable e IAsyncDisposable

Gli errori e gli avvisi del compilatore seguenti indicano problemi con l'implementazione o l'uso del modello dispose:

  • CS0245: Distruttori e object.Finalize non possono essere chiamati direttamente. Prendere in considerazione la possibilità di chiamare IDisposable.Dispose, se disponibile.
  • CS1674: il tipo usato in un'istruzione using deve essere convertibile in modo implicito in 'System.IDisposable'.
  • CS8410: il tipo usato in un'istruzione asincrona using deve essere convertibile in modo implicito in 'System.IAsyncDisposable' o implementare un metodo 'DisposeAsync' appropriato.
  • CS8417: il tipo usato in un'istruzione asincrona using deve implementare 'System.IAsyncDisposable' o implementare un metodo 'DisposeAsync' appropriato. Intendevi "using" anziché "await using"?
  • CS8418: il tipo usato in un'istruzione using deve implementare 'System.IDisposable'. Intendevi "await using" anziché "using"?

L'istruzione using garantisce l'eliminazione corretta delle risorse alla fine del using blocco. Per usare un tipo con un'istruzione using , deve implementare l'interfaccia di eliminazione appropriata. Per le istruzioni sincrone using, il tipo deve implementare IDisposable. Per le istruzioni asincrone await using , il tipo deve implementare IAsyncDisposable.

  • Impossibile chiamare Finalize direttamente (CS0245): non puoi chiamare direttamente un distruttore o il metodo Object.Finalize Il Garbage Collector invoca automaticamente i finalizzatori quando gli oggetti non vengono più referenziati. Per la pulizia deterministica, implementare IDisposable e chiamare invece il Dispose metodo .
  • Il tipo deve implementare IDisposable (CS1674): solo i tipi che implementano IDisposable possono essere usati in un'istruzione using . I tipi valore non implementano questa interfaccia e i parametri di tipo generico senza vincoli appropriati non possono essere considerati eliminabili. Applicare un vincolo di tipo, ad esempio where T : IDisposable quando si utilizzano tipi generici.
  • Il tipo deve implementare IAsyncDisposable (CS8410): i tipi usati con await using devono implementare IAsyncDisposable o fornire un metodo appropriato DisposeAsync . Se il tipo non supporta l'eliminazione asincrona, usare invece un'istruzione sincrona using o implementare l'interfaccia richiesta.
  • Modello di eliminazione non corrispondente (CS8417, CS8418): CS8417 si verifica quando si usa await using con un tipo che implementa solo IDisposable. CS8418 si verifica quando si usa using in modalità sincrona con un tipo che implementa solo IAsyncDisposable. Associare la using parola chiave all'interfaccia implementata dal tipo oppure implementare entrambe le interfacce se è necessario supportare entrambi i modelli.

Per altre informazioni, vedere Finalizzatori, Implementare un metodo Dispose e Implementare un metodo DisposeAsync.

Uso dell'ambito delle variabili e del flusso di controllo

Gli errori e gli avvisi del compilatore seguenti riguardano l'utilizzo non corretto delle variabili all'interno delle istruzioni del flusso di using controllo:

  • CS0728: assegnazione probabilmente errata alla variabile locale che è l'argomento di un'istruzione using o lock . La Dispose chiamata o lo sblocco verrà eseguita sul valore originale del locale.
  • CS8647: una variabile using non può essere usata direttamente all'interno di una sezione switch (prendere in considerazione l'uso di parentesi graffe).
  • CS8648: Non si può saltare a una posizione dopo una dichiarazione using.
  • CS8649: Non è possibile saltare a un punto prima di una dichiarazione di 'using' all'interno dello stesso blocco.

Le variabili dichiarate con using hanno regole di ambito specifiche che impediscono perdite di risorse. Il compilatore applica queste regole per garantire l'eliminazione corretta.

  • Assegnazione di variabile (CS0728): questo avviso indica che è stato assegnato un nuovo valore a una variabile che rappresenta la risorsa in un'istruzione using. La chiamata dispose viene eseguita sul valore originale, non sul valore appena assegnato, che può causare perdite di risorse. Inizializzare la risorsa nella dichiarazione dell'istruzione using anziché assegnarla in un secondo momento.

  • Uso di variabili nella sezione switch (CS8647): una using dichiarazione crea una variabile che è deallocata al termine del suo ambito. Se usato direttamente in una sezione switch senza parentesi graffe, l'ambito è ambiguo e può causare errori. Avvolgere il contenuto della sezione switch tra parentesi graffe per definire chiaramente lo scopo.

  • Istruzioni Goto e dichiarazioni using (CS8648, CS8649): non puoi usare istruzioni goto per saltare su dichiarazioni using perché il salto ignora la gestione appropriata delle risorse. CS8648 si verifica quando si passa in avanti su una using dichiarazione e CS8649 si verifica quando si passa indietro a una posizione prima di una using dichiarazione. Ristrutturare il codice per usare un flusso di controllo strutturato come cicli o spostare la using dichiarazione all'esterno della destinazione di salto.

Per altre informazioni, vedere l'istruzione using.

Dichiarazione non corretta using

  • CS9229: Non è possibile inserire modificatori nelle dichiarazioni using.

Una dichiarazione di variabile racchiusa in una dichiarazione using non può includere nessuno dei seguenti modificatori:

  • const
  • static
  • volatile
  • readonly
  • Modificatori di accessibilità: public, protected, internalprivate, , protected internaloprivate protected

L'esempio seguente genera l'errore CS9229:

using System;

class Program
{
    static void Main()
    {
        // error CS9229: Modifiers cannot be placed on using declarations.
        public using var resource = new Resource();

        // error CS9229: Modifiers cannot be placed on using declarations.
        static using var anotherResource = new Resource();
    }
}

class Resource : IDisposable
{
    public void Dispose() { }
}

Per correggere l'errore, rimuovere il modificatore dalla using dichiarazione:

using var resource = new Resource();

Per ulteriori informazioni, consultare l'istruzione using.