Blog
Blog HelionBlog HelionBlog HelionBlog Helion
  • Artykuły
  • Autorzy
  • Recenzje
  • Konkursy

C# — poprawna implementacja interfejsu IDisposable

    Blog.helion.pl Artykuły C# — poprawna implementacja interfejsu IDisposable
    NastępnyPoprzedni

    C# — poprawna implementacja interfejsu IDisposable

    By Jerzy Piechowiak | Artykuły, Programowanie | 1 komentarz | 3 marca, 2017 | 0

    C# jest językiem wysokiego poziomu, w którym przygotowano liczne gotowe komponenty i usprawnienia, jakich nie znajdziemy u konkurencji. Takie podejście ma sporo zalet, ponieważ nie musimy przejmować się wieloma rzeczami, które w innych językach musielibyśmy napisać sami. Oczywiście takie podejście ma również wady — w sytuacji gdy przydałoby się coś zmienić w gotowym komponencie, do którego kodu nie mamy dostępu. Nie o tym jest jednak dzisiejszy wpis.

    Jedną z istotnych zalet tego języka jest rozbudowany mechanizm zarządzania pamięcią, który robi wiele rzeczy za użytkownika. Tak naprawdę przeciętny programista C# nie musi zanadto przejmować się alokacją pamięci. Nie wiemy, kiedy dokładnie zwalniane są określone obiekty i ile zajmują one pamięci. Oczywiście, można uzyskać dostęp do takich informacji, choćby wykorzystując profiler czy niektóre klasy, ale w większości przypadków nie jest to potrzebne w codziennej pracy. Można powiedzieć, że dla wielu programistów C# w ich codziennym działaniu aspekt zarządzania pamięcią nie jest w ogóle problemem.

     

    Nie powinniśmy jednak do końca zapominać o alokacji pamięci w C#. Mimo że wiele się w tym przypadku dzieje poza nami, to w miarę możliwości warto kontrolować ten aspekt. Jest to szczególnie istotne w przypadku aplikacji z interfejsem graficznym, które często przechowują w pamięci kilka ekranów na stosie — użytkownik może do nich wrócić np. za pomocą przycisków zawartych w interfejsie użytkownika.

     

    W takiej sytuacji warto odpinać wszystkie niepotrzebne zdarzenia, odpowiednio używać bindingów (jeśli można, to w ogóle ich nie używać), a także poprawnie implementować interfejs IDisposable. I właśnie temu ostatniemu elementowi chcę poświęcić dzisiejszy wpis.

     

    Interfejs IDisposable

     

    Garbage Collector, dostępny w całym .Net Frameworku, działa na tyle dobrze, że łatwo o nim zapomnieć. Warto jednak nauczyć się z nim dobrze współpracować i wykorzystywać jego możliwości. Niezbędna w tym celu jest poprawna implementacja interfejsu IDisposable, którego bazowa postać bywa niewystarczająca, jeśli rozważamy właściwe zwalnianie zasobów zarządzanych i niezarządzanych.

     

    Poniżej standardowa implementacja:

     

    public class DisposableStandard : IDisposable
    {
    	#region IDisposable
    	public void Dispose()
    	{
    		// tu zwalniamy wszystkie zasoby
    	}
    	#endregion
    }
    

     

    Takie rozwiązanie, choć niesatysfakcjonujące, spełnia założenia interfejsu. Spójrzcie jednak na rozszerzoną i zalecaną implementację:

     

    public class DisposableExtended : IDisposable
    {
    	private bool isDisposed = false;
    	public void Dispose()
    	{
    		this.Dispose(true);
    		GC.SupressFinalize(this);
    	}
    	protected void Dispose(bool disposing)
    	{
    		if(!this.isDisposed)
    		{
    			if(disposing)
    			{
    				// tu zwalniamy zasoby zarządzane (standardowe klasy)
    			}
    			// tu zwalniamy zasoby niezarządzane (np. strumienie, obiekty COM itp.)
    		}
    		this.isDisposed = true;
    	}
    	~DisposableExtended()
    	{
    		this.Dispose(false);
    	}
    }
    

     

    Mamy tutaj wyraźny podział na zasoby zarządzane oraz niezarządzane. Ponadto pojawił się destruktor, który zwalnia zasoby niezarządzane użyte w naszej klasie.

     

    Powyższą implementację można zastosować w większości rozwiązań pisanych w C#. W rozwiązaniach przeznaczonych dla .Net Core nie będzie można skorzystać z poniższego polecenia:

     

    GC.SupressFinalize(this);

     

    Klasy, która implementuje interfejs IDisposable, możemy używać w bloku using. Sporym plusem takiego rozwiązania jest to, że po wyjściu z bloku automatycznie zostanie wywołana metoda Dispose na utworzonym w tym obszarze obiekcie. W ten sposób możemy używać tylko klas, które implementują interfejs IDisposable.

     

    using(var de = new DisposableExtended())
    {
    	// operacje na obiekcie de. Zostanie on zniszczony po wyjściu z bloku
    }
    

    Jerzy Piechowiak

    Altcontroldelete.pl

     


    Szukasz informacji o C#? Kliknij poniżej:

            

    c#, Jerzy Piechowiak, programowanie
    Avatar

    Jerzy Piechowiak

    Więcej postów od Jerzy Piechowiak

    Podobne posty

    • Ninject — ciekawa alternatywa dla Autofaca

      By Jerzy Piechowiak | Brak komentarzy

      W poprzednim poście starałem się przedstawić podstawowe różnice między trzema głównymi sposobami rejestracji usług dostępnymi w Autofacu. Kontener ten oferuje szerokie możliwości, dobre czasy „wyciągania” usług, ma także grono wiernych użytkowników. Jednak jeśli spojrzymy na statystykiCzytaj więcej…

    • Autofac — różne sposoby rejestracji usług

      By Jerzy Piechowiak | 2 komentarze

      Gdy dobrych kilka lat temu zaczynałem programować w C#, nie miałem pojęcia o czymś takim jak kontener IoC. Każdy obiekt tworzyłem klasycznie — poprzez zastosowanie słowa kluczowego new: StringBuilder sb = new StringBuilder();

    • Wzorzec projektowy adapter

      By Jerzy Piechowiak | Brak komentarzy

      Bardzo trudno jest napisać fragment kodu, o którym moglibyśmy powiedzieć, że jest idealny. Praktycznie niemożliwe jest zrobienie takiej rzeczy za pierwszym razem.

    • Wzorzec projektowy — metoda wytwórcza

      By Jerzy Piechowiak | Brak komentarzy

      Czasem mówi się, że wzorce projektowe uzupełniają braki techniczne w językach programowania. Jeśli spojrzymy na kilka popularnych wzorców, to szybko dostrzeżemy schemat. Wiele z nich krąży wokół szeroko rozumianego polimorfizmu.

    • Wzorzec projektowy singleton

      By Jerzy Piechowiak | Brak komentarzy

      Ze wzorcami projektowymi bywa różnie. Niektóre są bardzo przydatne, inne mniej, a jeszcze inne są pożądane tylko w określonych sytuacjach. Ogólnie bardzo łatwo wpaść w pułapkę nadużycia określonych rozwiązań. Taka sytuacja ma często miejsce wCzytaj więcej…

    NastępnyPoprzedni

    Znajdź post

    Bądźmy w kontakcie

    Książka dnia

    Wszechstronny JavaScript. Technologie: GraphQL, React, React Native i Electron

    Autor: Adam D. Scott

    Cena: 34.50 zł 69.00 zł
    (Cena e-booka: 34.50 zł 69.00 zł)

    O 35zł taniej!

    kup teraz

    Ostatnie wpisy

    • Błyskawiczny kurs pisania skryptów powłoki
    • Przykładowa aplikacja webowa zaimplementowana w ASP .NET Core
    • Wprowadzenie do .NET Core: instalacja, konfiguracja, pierwsza aplikacja w systemie Linux
    • Grupa Helion zaprasza na szkolenia stacjonarne!
    • Hello World! Czym jest programowanie?

    Tagi

    .net agile altcontroldelete asp.net c# czysty kod debugowanie design patterns e-biznes emarketing Google Google Analytics hacking Jerzy Piechowiak kod kodowanie Krzysztof Marzec książka Maciej Dutko magazyn programista Magdalena Daniłoś marketing MVVM onepress organizacja czasu praca prograista programista programowanie prokrastynacja rafał kocisz reklama rozwój software craftsman SOLID startup techniki programowania testowanie video marketing visual studio WPF wzorce projektowe youtube zarządzanie czasem zarządzanie projektami

    Archiwum

    • lipiec 2017
    • czerwiec 2017
    • maj 2017
    • kwiecień 2017
    • marzec 2017
    • luty 2017
    • styczeń 2017
    • grudzień 2016
    • listopad 2016
    • październik 2016
    • wrzesień 2016
    • lipiec 2016
    • czerwiec 2016
    Blog wydawnictwa
    Informatyka w najlepszym wydaniu
    Strona wydawcy:
    www.helion.pl
    Księgarnia Helion.pl
    Nowości
    Bestsellery
    Promocje
    Bądźmy w kontakcie:
    Chcesz zostać autorem?
    Masz pytania do redakcji?
    Napisz do nas »
    • Artykuły
    • Autorzy
    • Recenzje
    • Konkursy
    Blog Helion