2009-04-15 15 views
6

Mi piacerebbe davvero essere in grado di decorare la mia classe con un attributo di qualche tipo che imporrebbe l'uso di un'istruzione using in modo che la classe sia sempre disposta in modo sicuro ed evitare perdite di memoria. Qualcuno sa di una tale tecnica?È possibile imporre l'uso di un'istruzione using in C#

+0

Che dire di incorporare l'oggetto in un oggetto usa e getta diverso? –

+0

Decorare la classe con IDisposable è inteso come la bandiera per i consumatori della tua classe che dovrebbero essere inclusi in un Uso o chiamare Dispose. Se applichi la tecnica "Utilizzo", stai effettivamente dicendo ai tuoi buoni consumatori "Penso che tu sia troppo spesso per chiamare Dispose" e limitare l'uso. –

+0

Volevo anche dire, sei sicuro che non ci sono scenari in cui qualcuno potrebbe voler creare il tuo oggetto in un metodo e smaltirlo in un altro? (Forse sono anche identificabili). Stai rendendo impossibile per qualcuno farlo. –

risposta

13

Bene, c'è un modo in cui è possibile farlo: consentire l'accesso al proprio oggetto solo tramite un metodo statico che accetta un delegato. Come esempio molto semplificato (come ovviamente ci sono molti modi diversi di apertura di un file - lettura/scrittura, ecc):

public static void WorkWithFile(string filename, Action<FileStream> action) 
{ 
    using (FileStream stream = File.OpenRead(filename)) 
    { 
     action(stream); 
    } 
} 

Se le uniche cose capaci di creare un'istanza del vostro oggetto usa e getta sono metodi all'interno del tuo classe, puoi assicurarti che si abituino in modo appropriato. Certo, non c'è nulla che impedisca al delegato di prendere una copia del riferimento e provare a usarlo più tardi, ma non è proprio lo stesso problema.

Questa tecnica limita fortemente ciò che si può fare con il proprio oggetto, ovviamente - ma in alcuni casi può essere utile.

+2

Mi sono sentito un po 'sporco a fare qualcosa di simile a questo.* si sente meglio ora ha approvazione Skeet * –

+0

Questo non è un modello "nuovo" con qualsiasi mezzo - non che io possa ricordare il nome adesso ... –

5

È possibile utilizzare FxCop per applicare questa regola. Vedi la Wikipedia per un quick overview.

+0

Non aiuta quando le persone usano * le sue classi - non può dire ai suoi utenti di usare FxCop – ChrisF

+0

Buon punto. Ma questo è il loro problema ...: D –

+0

Fallo diventare parte della build e devi prestare attenzione ad esso. –

0

Se si desidera garantire che l'oggetto sia sempre disposto, utilizzare un finalizzatore in combinazione con IDisposable.

Ma prima di farlo, leggere su IDisposable e finalizzatori ed essere consapevoli del fatto che normalmente non sono necessari a meno che la classe non stia facendo qualcosa come gestire la durata di una risorsa non gestita.

Con un finalizzatore, il tuo oggetto verrà recuperato "alla fine", sia che venga incluso in un utilizzo o meno. L'istruzione using, che è una convenienza per IDisposable, consente la pulizia deterministica. L'unica avvertenza è che l'oggetto con i finalizzatori è più costoso da pulire e in generale rimane più a lungo in memoria mentre attendono la finalizzazione.

rif When do I need to implement a finalizer or IDisposable? o technorabble: Using Dispose, Finalizers and IDisposable