Domanda

ricevo un avviso quando si esegue un codice tramite il programma di utilità di analisi del codice di Visual Studio, che non sono sicuro di come risolvere. Forse qualcuno qui ha incontrato un problema simile, risolto, ed è disposto a condividere la loro conoscenza.

Sono la programmazione di una cella personalizzato dipinto utilizzato in un controllo DataGridView. Gli assomiglia codice:

public class DataGridViewMyCustomColumn : DataGridViewColumn
{
    public DataGridViewMyCustomColumn() : base(new DataGridViewMyCustomCell())
    {
    }

Si genera il seguente avviso:

CA2000: Microsoft.Reliability: Nel metodo 'DataGridViewMyCustomColumn.DataGridViewMyCustomColumn ()' chiamata System.IDisposable.Dispose sull'oggetto 'nuova DataGridViewMyCustomCell ()' prima di tutti i riferimenti ad esso sono fuori del campo di applicazione <. / p>

ho capito che mi sta avvisando DataGridViewMyCustomCell (o di una classe che eredita da) implementa l'interfaccia IDisposable e il metodo Dispose () dovrebbe essere chiamato per ripulire tutte le risorse rivendicate da DataGridViewMyCustomCell quando non è più.

Gli esempi che ho visto su internet suggerire un blocco utilizzando il campo di applicazione della durata dell'oggetto e hanno il sistema di disporre automaticamente, ma di base non viene riconosciuta quando viene spostato nel corpo del costruttore in modo da non posso scrivere un blocco utilizzando attorno ad esso ... che io non sono sicuro che avrei voluto fare in ogni caso, dal momento che non sarebbe che istruiscono la fase di esecuzione per liberare l'oggetto che potrebbe ancora essere utilizzato in seguito all'interno della classe di base?

La mia domanda, allora, è il codice va bene come è? O, come potrebbe essere riscritta per risolvere l'avvertimento? Io non voglio eliminare l'avviso meno che non sia veramente opportuno farlo.

È stato utile?

Soluzione

Se si utilizza Visual Studio 2010, allora CA2000 è completamente rotto. Essa può anche essere suddiviso in altre versioni di FxCop (anche noto come analisi del codice), ma VS2010 è l'unico che io posso garantire per. La nostra base di codice sta dando avvertimenti CA2000 per codice come questo ...

internal static class ConnectionManager 
{
    public static SqlConnection CreateConnection()
    {
         return new SqlConnection("our connection string");
    }
}

... indica che la connessione non è disposta prima che passa nell'ambito nel metodo. Beh, sì, è vero, ma non è fuori del campo di applicazione per l'applicazione come è tornato a un chiamante - questo è il punto centrale del metodo! Allo stesso modo, il vostro argomento del costruttore non sta andando fuori del campo di applicazione, ma viene passato alla classe base, quindi è un falso positivo dalla regola piuttosto che un problema reale.

Questa era una regola utile, ma ora tutto si può davvero fare è spegnerlo fino a quando non risolvere il problema. Il che è un peccato, perché i (pochissimi) positivi reali sono cose che dovrebbero essere risolti.

Altri suggerimenti

Non esiste un modo sicuro ed elegante per avere un costruttore Chained passare un nuovo oggetto IDisposable al costruttore di base, poiché, come si nota che non è possibile avvolgere la chiamata al costruttore incatenato in qualsiasi tipo di blocco try finally. V'è un approccio che è sicuro, ma non è certo elegante: definire un metodo di utilità qualcosa come:

internal static TV storeAndReturn<TR,TV>(ref TR dest, TV value) where TV:TR
{ 
  dest = value; return value;
}

Dai il costruttore aspetto qualcosa di simile:

protected DataGridViewMyCustomColumn(ref IDisposable cleaner) : 
   base(storeAndReturn(ref cleaner, new DataGridViewMyCustomCell()))
{
}

Codice, che ha bisogno di un nuovo oggetto dovrebbe quindi chiamare un metodo factory public static che chiama il costruttore appropriato all'interno di un / blocco try finally cui principale linea sarebbe nullo fuori cleaner poco prima è finito, e il cui blocco finally chiamerebbe Dispose su cleaner se non è nullo. A condizione che ogni sottoclasse definisce un metodo factory simile, questo approccio assicura che il nuovo oggetto IDisposable otterrà disposto anche se si verifica un'eccezione tra tempo è creato e il tempo l'oggetto incapsulante è esposto al codice client. Il modello è brutto, ma non sono sicuro che qualsiasi altro modello più bello sarebbe assicurare la correttezza.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top