2010-06-07 22 views
18

Pracuję nad dużym projektem, a jednym z moich zadań jest usunięcie ewentualnych wycieków pamięci. W moim kodzie zauważyłem, że nie można pozbyć się kilku identyfikowalnych przedmiotów i to naprawiłem. Jednak to prowadzi mnie do bardziej podstawowego pytania, jak znaleźć wszystkie klasy używane w moim projekcie, który implementuje IDisposable? (Nie tworzone niestandardowo klasy, ale standardowe klasy biblioteki, które zostały użyte).
Znalazłem już jedną mniej niż oczywistą klasę, która implementuje IDisposable (DataTable implementuje MarshalByValueComponent, który dziedziczy IDisposable). W tej chwili ręcznie sprawdzam wszelkie podejrzane klasy za pomocą MSDN, ale czy nie jest jakiś sposób, za pomocą którego mogę zautomatyzować ten proces?
Jak znaleźć wszystkie klasy implementujące IDisposable?

+1

można powiedzieć, że FxCop? – Arseny

Odpowiedz

17

Reflector może pokazać, które klasy wdrożyć IDisposable: wystarczy zlokalizować interfejs reflektor IDisposable i rozwinąć „pochodzący typy” węzeł

Inną opcją, z kodu, jest skanowanie wszystkich załadowanych zestawów dla typy realizacji IDisposable:

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

Powyższy fragment kodu skanuje wszystkie załadowane zespoły (zamiast tylko zespołu wykonującego) i nadaje wszystkie typy jednorazowe posortowane według przestrzeni nazw, dlatego bardzo łatwo jest sprawdzić, czy dany typ jednorazowy został pominięty. Tx bardzo mocno :) – apoorv020

0

Myślę, że coś jak poniższy kod może działać. Musiałby on zostać dostosowany, aby załadować prawidłowy zestaw, jeśli jest uruchamiany z zewnętrznego narzędzia.

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

To nie jest dokładnie to, czego szukałem. Ten kod wykonuje pętlę nad typami zdefiniowanymi jako w bieżącym złożeniu, podczas gdy chcę go uruchomić na typach, które są używane w bieżącym złożeniu w postaci.
Mogę łatwo sprawdzić, czy jedna z klas zdefiniowanych w moim projekcie jest IDisposable, jednak chcę sprawdzić, czy standardowe biblioteki klas, które używam narzędzi IDisposable, czy nie. – apoorv020

+0

@ apoorv020: Powinien być w stanie uruchomić powyższy kod na zespołach szkieletowych .NET (które są przywoływane przez twój projekt), jak myślę, a następnie możesz zapisać listę wszystkiego, co implementuje 'IDisposable', a następnie po prostu wyszukujesz kod źródłowy dla czegokolwiek na tej liście? –

+0

Kod "Thomas Levesque" robi dokładnie to. Dzięki za odpowiedź, wskazała mi to we właściwym kierunku. – apoorv020

0

spróbować tej kwerendy LINQ:

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

Nie sądzę, że to zadziała, komentarz z MSDN: * Metoda IsSubclassOf nie może być używana do określenia, czy interfejs pochodzi z innego interfejsu, czy klasa implementuje interfejs * –

+0

dzięki za poprawkę. –

7

testowy projekt z FxCop. Może przechwytywać wszystkie miejsca, w których obiekty IDisposable nie są usuwane. Być może będziesz musiał wykonać pewną pracę, aby wyłączyć wszystkie nieistotne reguły FxCop, pozostawiając tylko reguły związane z IDisposable.

Na przykład, jest to jedna z zasad FxCop IDisposable: http://msdn.microsoft.com/en-us/library/ms182289%28VS.100%29.aspx

Uwaga: trzeba znaleźć zarówno własne, .NET i osób trzecich obiektów IDisposable, które nie są prawidłowo obsługiwane.

3

NDepend można użyć do analizy projektu i znaleźć wszystkie typy, które implementują IDisposable.

Here's że kwerenda CQI dla wyniku

SELECT TYPES WHERE Implement "System.IDisposable" 
Powiązane problemy