2010-06-07 15 views
18

Sto lavorando a un progetto di grandi dimensioni e uno dei miei compiti è rimuovere possibili perdite di memoria. Nel mio codice, ho notato diversi oggetti non identificabili che non vengono smaltiti e ho risolto il problema. Tuttavia, questo mi porta a una domanda più basilare, come faccio a trovare tutte le classi utilizzate nel mio progetto che implementa IDisposable?? (Non classi create dall'utente ma classi di libreria standard che sono state utilizzate).
Ho già trovato una classe meno che ovvia che implementa IDisposable (DataTable implementa MarshalByValueComponent, che eredita IDisposable). In questo momento, sto controllando manualmente qualsiasi classe sospetta utilizzando MSDN, ma non c'è un modo attraverso il quale posso automatizzare questo processo?Come trovare tutte le classi che implementano IDisposable?

+1

può FxCop dire che? – Arseny

risposta

17

Reflector può visualizzare quali classi implementano IDisposable: basta individuare l'interfaccia IDisposable in Reflector, ed espandere i "tipi derivati" nodo

Un'altra opzione, dal codice, è quello di analizzare tutti assembly caricati per i tipi di applicazione IDisposable:

var disposableTypes = 
    from a in AppDomain.CurrentDomain.GetAssemblies() 
    from t in a.GetTypes() 
    where typeof(IDisposable).IsAssignableFrom(t) 
    select t; 
+0

Questa parte di codice sopra, analizza tutti gli assembly caricati (anziché solo l'assembly in esecuzione) e fornisce tutti i tipi eliminabili ordinati per spazio dei nomi, quindi è molto semplice verificare la presenza di qualsiasi tipo di disposable perso. Tx molto :) – apoorv020

0

Penso che qualcosa come il seguente codice potrebbe funzionare. Dovrebbe essere regolato per caricare l'assembly corretto se eseguito da uno strumento esterno però.

Assembly asm = Assembly.GetExecutingAssembly(); 
foreach (Type type in asm.GetTypes()) 
{ 
if(type.GetInterface(typeof(IDisposable).FullName) != null) 
{ 
    // Store the list somewhere 
} 
} 
+0

Questo non è esattamente quello che stavo cercando. Questo codice scorre sui tipi definiti nell'assieme corrente, mentre io voglio eseguirlo sui tipi che sono utilizzati nell'assieme corrente.
Posso verificare facilmente se una delle classi definite nel mio progetto non è idonea, ma voglio verificare se le classi di libreria standard che sto usando implementano IDisposable o no. – apoorv020

+0

@ apoorv020: Dovrebbe essere in grado di eseguire il codice sopra negli assembly di framework .Net (qualsiasi riferimento al progetto) anch'io penserei, quindi è possibile salvare un elenco di tutto ciò che implementa 'IDisposable' e quindi fai una ricerca attraverso il tuo codice sorgente per qualcosa in quella lista? –

+0

Il codice di "Thomas Levesque" fa esattamente questo. Grazie per la tua risposta, però, mi ha indirizzato nella giusta direzione. – apoorv020

0

Prova questa ricerca LINQ:

var allIdisposibles = from Type t in Assembly.GetExecutingAssembly().GetTypes() 
         where t.GetInterface(typeof(IDisposable).FullName) != null && t.IsClass 
         select t; 
+2

Non pensare che funzionerebbe, commento da MSDN: * Il metodo IsSubclassOf non può essere utilizzato per determinare se un'interfaccia deriva da un'altra interfaccia, o se una classe implementa un'interfaccia * –

+0

grazie per la correzione. –

7

prova il vostro progetto con FxCop. Può catturare tutti i luoghi in cui non sono disposti oggetti idisposti. Potrebbe essere necessario fare del lavoro per disabilitare tutte le regole FxCop irrilevanti, lasciando solo le regole relative a IDisposable.

Per esempio, questo è uno di regole FxCop IDisposable: http://msdn.microsoft.com/en-us/library/ms182289%28VS.100%29.aspx

Nota: è necessario trovare sia il proprio, .NET e gli oggetti IDisposable di terze parti che non sono gestiti correttamente.

3

È possibile utilizzare NDepend per analizzare il progetto e trovare tutti i tipi che implementano IDisposable.

Here's le query CQL per il risultato

SELECT TYPES WHERE Implement "System.IDisposable" 
Problemi correlati