Wie wichtig ist es Destruktor und Dipsose Funktion in Klassen zu implementieren?
-
Hallo Leute,
durch den GC muss man sich ja eigentlich nicht mehr um die Zerstörung von Objekten Kümmern. Aber sollte trozdem Destruktoren und Dispose Funktionen in die Klassen implementiert werden? Oder ist das nur in Speicherkritischen Teilen notwendig?
-
Hallo,
du musst da bissle aufpassen, du bringst zwei Dinge durcheinander. Der GC kann managed Objekte zerstören, da muss man nichts selber machen, macht alles der GC wenn er meint er muss jetzt aufräumen.
IDisposable dagegen implementiert man wenn man unmanaged Resourcen hat die man aufräumen muss, da der GC keine Möglichkeit hat diese aufzuräumen. Besonders tückisch ist dass manche Klassen im Framework unmanaged Resourcen benutzen wo man es erst gar nicht vermutet, z.B. beim Zeichen die Pens und Brushes. Die muss man unbedingt disposen da man sonst schnell Gefahr läuft ne OutOfMemoryException zu bekommen.
Sprich GC erledigt alle managed Objekte, Dispose alle unmanaged Objekte. Von daher stimmt deine Ursprungsfragestellung nicht ganz da GC und Dispose zwei verschiedene Arten von Resourcen freigeben. Der Destruktor (besser Finalizer) ist eigentlich nur nen Hilfsmittel um zu erreichen das der GC die Dispose Funktion automatisch mit aufruft. Mehr macht der nicht.
-
Ok danke,
aber woher weis ich welche Ressource unmanaged sind? Würde ich bspw. CLI/c++ Code teile mit unmanaged Ressource verwenden dann ok, aber wenn ich rein in C# programmiere geh ich ja davon aus das der GC alles macht, d.h. es gibt in C# auch Ressource welche unmanaged sind wie PEn und Brushes???
-
@DestruktorMan:
Ob du einen Finalizer implementieren musst oder nicht hängt davon ab ob du *direkt* unmanaged Resourcen freigeben musst.
Wenn du in der Situation bist weisst du es, da du z.B. irgendwo "CloseHandle" oder "DeleteObject" oder ähnliches aufrufen müsstest. In solchen Fällen brauchst du einen Finalizer (und IDisposable.Dispose solltest du dann natürlich auch implementieren).----
Ob du IDisposable implementieren musst hängt davon ab ob
- Du selbst deterministische Finalisierung brauchst (z.B. wenn du ein Objekt am Ende seines "Lebens" aus irgendwelchen Listen austragen musst).
UND - Ob dein Objekt von Klassen abgeleiete ist, bzw. "Unterobjekte besitzt" die IDisposable implementieren.
Beispiel für 1: du willst irgendwelche Events unhooken wenn das Objekt nichtmehr gebraucht wird. Also implementierst du IDisposable, damit der User "Dispose" verwenden kann wenn er das Objekt nichtmehr braucht.
Beispiel für 2: du verwendest in deiner Klasse ein File oder einen Socket. Also implementierst du IDisposable, damit du in der Dispose Funktion das File oder den Socket "disposen" kannst.
In diesen Fällen einen Finalizer zu implementieren macht eigentlich keinen Sinn.
- Du selbst deterministische Finalisierung brauchst (z.B. wenn du ein Objekt am Ende seines "Lebens" aus irgendwelchen Listen austragen musst).
-
Müsste man den an sich nicht auch implementieren, wenn man Member hat, die IDisposable implementieren ? i.d.R. wird es ja aus den von Dir genannten Gründen implementiert. Packt das jemand in eine Klasse, die das nicht implementiert, bleiben die Ressourcen doch wieder offen bis der GC aufräumt.
-
- Ob dein Objekt von Klassen abgeleiete ist, bzw. "Unterobjekte besitzt" die IDisposable implementieren.
Damit waren Member gemeint, wenn das Objekt "ownership" hat.
Wenn ich eine Klasse habe die ein paar Files als Member hat, deren Lifetime aber nicht kontrolliert, dann muss die nicht disposable sein.
-
Ups, zu hektisch gelesen