2009-06-23 10 views
16

Zastanawiałem się, czy istnieje jakiś rodzaj ściągawki dla których sprzeciwia się dobrze przy użyciu instrukcji ... SQLConnection, MemoryStream itpCzy istnieje lista wspólnych obiektów, które implementują IDisposable dla instrukcji using?

Biorąc to krok dalej, byłoby wspaniale nawet pokazać drugi "Kawałki układanki", tak jak powinno się zadzwonić pod connection.Close() przed nawiasem zamykającym za pomocą instrukcji.

Coś takiego istnieje? Jeśli nie, może powinniśmy ją stworzyć.

+0

Dlaczego chcesz zadzwonić do połączenia.Zamknij() przed nawiasem końcowym? Nie wiem, że w układance jest wiele innych elementów. –

+0

Dlaczego lista? Możesz łatwo sprawdzić, czy obiekt implementuje IDisposable. – Groo

+0

@Groo: Naprawdę musisz sprawdzić dokumenty, niektóre typy ukrywają Dispose(). To nie takie proste. –

Odpowiedz

10

Microsoft FxCop ma regułę sprawdzającą, czy używasz IDisposbale w użyciu bloku.

1

Za pomocą programu ReSharper można wyświetlić wszystkie wyprowadzone typy. Być może możesz to zrobić za pomocą przeglądarki obiektów bez ReSharpera. Przejdź do definicji interfejsu i poszukaj "pokaż spadkobierców".

+0

Nie znając ReSharper, robi to pracujesz dla interfejsów? I czy jest to Projekt w całym tekście czy możesz dołączyć GAC i inne foldery? –

+0

Działa na wszystko i może zawierać zespoły biblioteki, w tym te w GAC. Możesz także kliknąć przypisanie i zasugeruje użycie bloku, jeśli przypisany typ narzędzi IDisposable. –

4

Jeśli nie masz pewności, czy klasa implementuje IDisposable, czy nie, zamknij ją w bloku using niezależnie. Jeśli pojawi się błąd kompilacji, po prostu go usuń. Stracisz tylko kilka sekund na pisanie.

+0

To prawda, działa to jak urok. –

+1

W większości przypadków, jeśli istnieje metoda usuwania, zaimplementuje IDisposable. – weiqure

+0

@weiqure - ale nie vice versa –

2

Prostym sposobem na uzyskanie listy typów implementujących IDisposable jest złamanie Reflectora, przejście do System.IDisposable, rozwinięcie węzła, a następnie rozwinięcie węzła "Derived Types".

Aby upewnić się, że lista jest kompletna, sprawdź, czy wszystkie używane zestawy są "Otwarte w odbłyśniku.

7

Następująca metoda C# będzie zawierała listę wszystkich możliwych do zsynchronizowania typów znalezionych w określonym zestawie. (Używane przestrzenie nazw: System, System.Collections.Generic, System.IO, System.Reflection)

static void PrintDisposableTypesFromFile(String path) 
    { 
    Assembly assembly = Assembly.LoadFrom(path); 
    foreach (Type type in assembly.GetTypes()) 
     if (type.GetInterface("IDisposable") != null) 
      Console.WriteLine(type.FullName); 
    } 

Poniższa metoda C# korzysta z poprzedniego zrobić to samo dla wszystkich zespołów w katalogu i jego podkatalogów np „C: \ WINDOWS \ Microsoft.NET \ Framework \ v2.0.50727”:

static void PrintDisposableTypesFromDirectory(DirectoryInfo dir, bool warn) 
    { 
    foreach (FileInfo file in dir.GetFiles("*.dll")) 
    { 
     try 
     { 
      PrintDisposableTypesFromFile(file.FullName); 
     } 
     catch (Exception ex) 
     { 
      if (warn) 
      { 
       Console.Error.WriteLine(
       String.Format(
        "WARNING: Skipped {0}: {1}", 
        new object[] { file.FullName, ex.Message })); 
      } 
     } 
    } 
    // recurse 
    foreach (DirectoryInfo subdir in dir.GetDirectories()) 
     PrintDisposableTypesFromDirectory(subdir, warn); 

    } 

nie jestem pewien lista wszystkich jednorazowych jest bardzo użyteczny, ale użyłem podobnego kodu, aby znaleźć inne ciekawe rzeczy podobnie jak pełna lista kodowań tekstowych obsługiwanych przez platformę .NET.

+0

+1 za wysiłek, ale myślę, że łatwiej byłoby po prostu użyć reflektora :) –

0

Szybki, brudny sposób sprawdzenia, czy dany typ implementuje IDisposable, polega na utworzeniu jego egzemplarza i sprawdzeniu, czy wystąpienie ma funkcję składową Dispose(). Jeśli tak, możesz być w 99% pewien, że implementuje IDisposable.

3

Oprócz innych odpowiedzi, należy pamiętać, że klasa może implementować IDisposable, ale nie ma Dispoin na liście intellisense.

class MyClass :IDisposable 
{ 
    void IDisposable.Dispose() 
    { 
     /* Stuff */ 
    } 
} 
2

Jeśli używasz Visual Studio można nacisnąć klawisz F12 na deklaracji typu potrwa do ekranu meta-danych lub definicji klasy (jeśli masz kodu źródłowego). Jeśli twoje klawisze są różne, kliknij prawym przyciskiem myszy i "przejdź do definicji". Stamtąd możesz zobaczyć, co zaimplementuje dana klasa. Proponuję zrobić to dla wszystkich klas, gdy pierwszy raz ich spotkasz, aby uzyskać "wyczucie" tego, co klasa może zrobić.

+2

Tak, ale nie każda klasa implementująca IDisposable implementuje ją bezpośrednio. Weźmy na przykład DataTable (który, BTW, nie musisz usuwać ... ale to kolejna rozmowa http://stackoverflow.com/questions/913228/może-i-dispose-dataset-and-datatable.) – Grinn

14

Być może rzucić okiem na mój wpis na ten temat na http://www.lancemay.com/2010/01/idisposable-cheat-sheet/. Nie jestem pewien, czy tego właśnie szukasz, ale na podstawie pierwotnego pytania brzmi to tak, jak być może.

+2

Cool ! Właśnie tego początkowo szukałem! –

+0

wow tak wiele komentarzy, a to jest odpowiedź! dzięki Lance! – aron