2009-10-30 14 views
7

Jaka jest różnica między dwiema następującymi fragmenty kodu:Różnica między "używaniem" a określaniem zakresu?

using (Object o = new Object()) 
{ 
    // Do something 
} 

i

{ 
    Object o = new Object(); 
    // Do something 
} 

I zaczęła używać using dużo więcej, ale jestem ciekaw, co faktycznie korzyści w porównaniu do określania obiektów.

Edit: Przydatne ciekawostki wziąłem z tego:

Jon Skeet:

Należy pamiętać, że to nie wymusza zbieranie śmieci w jakikolwiek sposób, kształt lub formę. Usuwanie śmieci i szybkie usuwanie zasobów są nieco ortogonalne.

Will Eddins komentarz:

Chyba że klasa implementuje interfejs IDisposable i posiada funkcję Dispose(), aby nie używać użyciu.

Odpowiedz

20

Pierwszy fragment nazywa Dispose na końcu bloku - można tylko zrobić to z typów, które realizują IDisposable, i to w zasadzie nazywa Dispose w bloku finally, więc można go używać z typów, które wymagają oczyszczenia zasobów do góry, np

using (TextReader reader = File.OpenText("test.txt")) 
{ 
    // Use reader to read the file 
} 
// reader will be disposed, so file handle released 

Zauważ, że to robi nie siła garbage collection w jakikolwiek sposób, kształt lub formę. Usuwanie śmieci i szybkie usuwanie zasobów są nieco ortogonalne.

Zasadniczo powinieneś użyć instrukcji using dla prawie wszystkiego, co implementuje IDisposable i za który blok kodu będzie odpowiedzialny (w zakresie czyszczenia).

+0

Czy można słusznie powiedzieć, że ma to zastosowanie głównie wtedy, gdy trzeba oczyścić niezarządzane zasoby, które może posiadać klasa? Czy dotyczy to również klas czysto zarządzanych? –

+0

+1 za notatkę dotyczącą zbierania śmieci, zawsze mam tendencję do jej zapominania ... – jdehaan

+0

Ok, więc typowy obiekt służący do przechowywania struktury danych nie widziałby żadnej korzyści z klauzuli using, ale cięższego obiektu, który implementuje IDisposable będzie? – Kelsey

3

Pod koniec using obiekt zostaje usunięty (obiekt, który umieścisz w nawiasie, musi zaimplementować IDisposable). Obiekt zostaje usunięty również w wyjątkowych przypadkach. I nie musisz czekać, aż GC zrobi to w pewnym momencie (ty to kontrolujesz).

EDIT: Wadą scopingu są:

  • nie kontrolować rozmieszczenie obiektu
  • nawet jeśli można by nazwać wyrzucać na końcu zakresu, to nie byłoby bezpieczne wyjątek
1

Zobacz dokumentację dotyczącą IDisposable i możliwej do określenia alokacji zasobów.

Po prostu, na końcu blokumożna niezawodnie uzyskać dysponować przydzielonymi zasobami (np. Zamknąć uchwyty plików, połączenia z bazami danych itp.)

0

using wymaga jedynie wdrożenia interfejsu IDisposable i wywołuje metodę Dispose na końcu zakresu.

Dla wielu wściekłych argumentów na temat właściwego usuwania obiektów, istnieje wiele innych wątków.

3

Wystarczy dosłownie pokazać różnicę ...

using (FileStream fileStream = new FileStream("log.txt", FileMode.OpenCreate)) 
{ 
    //stuff with file stream 
} 

jest taki sam jak ...

{ 
    FileStream fileStream = new FileStream("log.txt", FileMode.OpenCreate); 

    try 
    { 
    //stuff with filestream 
    } 
    finally 
    { 
    if (fileStream != null) 
     ((IDisposable)fileStream).Dispose(); 
    } 
} 

gdzie jako

{ 
    FileStream fileStream = new FileStream("log.txt", FileMode.OpenCreate); 
    fileStream.Dispose(); 
} 

jest jak jest.

+0

+1 na dobry przykład. – Kelsey

Powiązane problemy