2010-03-12 14 views
29

Qual è la migliore pratica per quando implementare IDisposable?Quando devo implementare IDisposable?

È la migliore regola empirica per implementarlo se si dispone di un oggetto gestito nella classe o dipende se l'oggetto è stato creato nella classe o appena passato? Dovrei farlo anche per le classi senza oggetti gestiti?

+2

@Earwicker: Se hai trovato più di quello che ho fatto su quell'argomento, allora mi piacerebbe che tu lo condividessi con me. – Bobby

+2

http://stackoverflow.com/search?q=IDisposable+owner –

risposta

26

Se intendete gli oggetti non gestiti allora sì, dovreste implementarlo ogni volta che avete una o più risorse non gestite che state trattando nella vostra classe. Dovresti anche usare il pattern quando ti stai aggrappando agli oggetti che sono idisposibili e assicurati di eliminarli quando la tua classe viene eliminata.

(accordo sul fatto che questa domanda è già stata posta sufficiente di volte per eseguire una piccola stampante senza inchiostro dovrebbero essere stampati ...)

6

È necessario implementare IDisposable quando la classe contiene le risorse che si desidera rilasciare al termine dell'utilizzo.

0

Se ha proprietà che devono anche essere smaltite.

6

Quando la classe contiene oggetti non gestiti, le risorse, i file aperti o oggetti di database , è necessario implementare IDisposable.

4

Penso che the docs siano abbastanza chiari su ciò che è adatto per IDisposable.

L'utilizzo principale di questa interfaccia è per rilasciare risorse non gestite. Il garbage collector rilascia automaticamente la memoria assegnata a un oggetto gestito quando tale oggetto non è più utilizzato da . Tuttavia, non è possibile prevedere quando si verificherà la raccolta di immondizia . Inoltre, il garbage collector non ha conoscenze di risorse non gestite come handle di finestre o file aperti e flussi.

Ha anche un esempio. In questo esempio la classe che implementa IDisposable contiene un handle. Una maniglia deve essere liberata quando non viene più utilizzata. Questo viene fatto nel metodo Dispose(). Quindi l'utente di quella classe vede che implementa IDisposable e sa che la classe deve essere eliminata esplicitamente quando non è più necessaria (in modo che l'handle possa essere liberato). È una buona pratica (regola generale) che tu debba sempre chiamare Dispose() nelle istanze IDisosable quando l'istanza non è più necessaria.

10

Mentre tutti hanno menzionato risorse (non gestite), ho un'altra cosa da aggiungere: la uso quando ho bisogno di eliminare i collegamenti del gestore di eventi che altrimenti impedirebbero a una classe di uscire dal campo di applicazione e di essere spazzata via.

Ad esempio, ho un servizio che viene iniettato in una vista figlio, quella vista figlio si iscriverà a vari eventi di tipo finito asincrono sul servizio. Il proprietario di quella vista figlio non ha idea di quale sia il tipo concreto, ha semplicemente come interfaccia. In futuro il servizio potrebbe non essere più disponibile in alcun punto arbitrario, e non voglio che non funzioni in GC. Dopo aver eliminato quella vista secondaria, il proprietario chiamerà Dispose su di essa per dargli la possibilità di sganciare qualsiasi gestore di eventi. Ecco un esempio leggermente forzato (e molto pseudo codice), si noti come l'interfaccia per la vista figlio implementa anche IDisposable.

public class OwnerView { 

    public OwnerView() { 
     _childView = new ChildView(myServiceReference); 
    } 

    public void CloseChildView() { 
     if (childView != null) { 
      _childView.Close(); 
      _childView.Dispose(); 
     } 

     _childView = null; 
    } 

    private IChildView _childView; 
} 

public class ChildView : IChildView { 

    public ChildView(MyService serviceRef) { 
     _serviceRef = serviceRef; 
     _serviceRef.GetSettingsAsyncFinished += new EventHandler(someEventHandler); 
    } 

    public void IDisposable.Dispose() { 
     _serviceRef -= someEventHandler; 
    } 

    private MyService _serviceRef; 
} 

public interface IChildView : IDisposable { 
    void DoSomething(); 
    ... etc ... 
} 

ci sono di gran lunga più autorevoli commenti su questo dagli altri su SO, come Do event handlers stop garbage collection from occuring? e Garbage collection when using anonymous delegates for event handling. Si consiglia inoltre di controllare questo articolo codeproject.

Problemi correlati