2016-04-23 12 views
17

Ho visto così tante volte gli sviluppatori che utilizzano un oggetto monouso in linea, ad esempio here. Con linea intendo:È sicuro creare e utilizzare un oggetto monouso in linea?

var result = new DataTable().Compute("1 + 4 * 7", null); 

So che il metodo Dispose non sarà chiamato, ma dal momento che nessun riferimento è ritenuta l'oggetto, come sarà il garbage collector gestirlo? È sicuro usare un oggetto monouso del genere?

Nel mio esempio ho utilizzato un DataTable perché è l'unico esempio concreto che ho trovato, ma la mia domanda si applica agli oggetti monouso in generale. Non li uso personalmente in questo modo, volevo solo sapere se sono gestiti diversamente dal GC se vengono utilizzati in questo modo.

+0

Sebbene questo non risponda alla tua domanda generale, parla al tuo esempio http://stackoverflow.com/questions/913228/should-i-dispose-dataset-and-datatable – hatchet

+4

Questo snippet è stato scritto da uno smart programmatore che sapeva che DataTable non ha nulla usa e getta e in realtà non implementa Dispose(). Molti programmatori .NET sono molto a disagio a riguardo. Quindi, non farlo in questo modo, non diventa molto più brutto quando usi l'istruzione * using *. Puoi stare bene senza mai sbagliare. –

risposta

11

Il problema chiave qui è il momento in cui viene chiamato Dispose, che è solo sconosciuto nel tuo esempio (fornendo una buona implementazione di IDisposable - vedi sotto). Prenderò in considerazione l'utilizzo di un'istanza IDisposable senza un'istruzione using un odore di codice. La classe sta implementando IDisposable per un motivo, e quindi tu come utente devi rispettare il suo contratto.

Tuttavia, notare che in un correct implementation di IDisposable il finalizzatore della classe gestisce lo smaltimento di un oggetto non disposto. Quindi, anche se non è istanziato all'interno di uno using, lo smaltimento deve essere eseguito, ma in un tempo sconosciuto e su un thread diverso (del GC).

Volevo solo sapere se sono gestiti diversamente dal GC se vengono utilizzati in questo modo.

No, il GC tratta tutti gli oggetti allo stesso modo e non tratta le implementazioni IDisposable in modo diverso. Tuttavia, in una corretta implementazione di IDisposable il metodo Finalize (invocato dal GC su ogni oggetto a meno che non venga soppresso su base per oggetto) porterebbe a invocare lo Dispose.

+2

Devo essere d'accordo. Anche se ci sono alcune classi in cui è relativamente innocuo non disporne esplicitamente, sembra un'abitudine molto scarsa da sviluppare. – hatchet

1

Se l'oggetto inizializzato in linea ha implementato un distruttore, tale distruttore potrebbe chiamare Dispose() dopo che l'oggetto è andato fuori ambito.

Tuttavia, il modo più pulito e corretto consiste nell'utilizzare un'istruzione using perché ciò potrebbe potenzialmente portare solo a casi di oggetti che si aggirano senza scopo.

+4

Gli oggetti C# non hanno distruttori. Potrebbero * avere finalizzatori. I finalizzatori non vengono eseguiti quando gli oggetti escono dall'ambito. Corrono quando GC pensa che sia il momento di eseguirli. – GSerg

+0

Mi stai prendendo in giro? https://msdn.microsoft.com/en-us/library/66x5fx1b.aspx –

+1

Dal tuo link: "Il programmatore non ha il controllo su quando viene chiamato il distruttore perché questo è determinato dal garbage collector" –

1

In questo modo non è sicuro utilizzare oggetti monouso. Sì, non si terrà alcun riferimento, ma lo scopo del modello usa e getta è quello di smaltire tutte le risorse non gestite (come gli handle del sistema operativo) che non possono essere raccolti.

+2

Le risorse non gestite verranno rilasciate durante la raccolta dati inutili se non sono state precedentemente eliminate da una chiamata esplicita a 'IDisposable.Dispose()'. Ovviamente, ciò presuppone che 'IDisposable' sia implementato correttamente e che il finalizzatore rilasci la risorsa non gestita. Quindi è effettivamente "sicuro" non disporre di un oggetto usa e getta quando non è più usato e lasciarlo al garbage collector per ripulirlo. Tuttavia, non è molto intelligente o efficiente. –

Problemi correlati