Einzelnen Beitrag anzeigen

OregonGhost

Registriert seit: 8. Jun 2002
Ort: Lübeck
1.216 Beiträge
 
Delphi 3 Professional
 
#24

Re: [C#] Fragen zu automatisch generiertem Code

  Alt 25. Jul 2004, 11:20
Nur um das nochmal klarzustellen:
Es gibt in C# keine Destruktoren wie in z.B. C++ oder Delphi. Destruktoren werden für die deterministische Zerstörung von Objekten eingesetzt und sind in .net sowie in C# so NICHT vorhanden.
Das, was man in C# als Destruktoren bezeichnet und was auch aussieht wie ein C++-Destruktor, ist in Wirklichkeit ein Finalizer! Es hat dieselbe Semantik wie die Finalizer der anderen .net Sprachen. Hierbei sollen die Objekte auch zerstört werden, aber der Vorgang ist nicht deterministisch!
Genauer ist ein so genannter Destruktor in C# also nur eine bequeme Methode, die Object.Finalize()-Methode zu überschreiben und dabei implizit (was man sonst von Hand machen müsste) base.Finalize() aufzurufen.
Managed C++ hingegen unterstützt zusätzlich einen deterministischen Destruktor, der aber vom Compiler erzeugt wird und keine CLR-Unterstützung genießt.

Zitat von Microsoft:
Hinweis Trotz der scheinbaren Ähnlichkeit haben die Destruktoren in C# und den verwalteten Erweiterungen nicht die gleiche Semantik wie Destruktoren in nicht verwaltetem C++. Verwalteter Code unterstützt keine Semantik für Destruktoren, die der von C++ gleicht.
Es gibt also in C# Destruktoren, aber diese sollten nicht mit Destruktoren aus nicht gemanageten Sprachen verglichen werden. Dispose (wie weiter oben geraten) ist zudem weder Finalizer noch Destruktor.

Zitat von Generalissimo:
Stimmt. Nur soll man ihn nicht wirklich bzw. nur in speziellen Fällen einsetzen. Sprich in Situationen wo man genau wissen muss, wann ein Objekt freigegeben wird. Ohne Destruktor macht das der Garbage Collector selbst, jedoch ist dabei der Zeitpunkt der Freigabe unbekannt.
Falsch! In C# gibt es keine deterministische Zerstörung von Objekten. Der Garbage Collector macht es IMMER selbst. Er ruft auch den Finalizer auf, falls die Klasse ihn überschrieben (sprich einen so genannten Destruktor definiert) hat! Man kann den Garbage Collector mit ein paar Tricks beeinflussen oder Objekte am Leben erhalten, aber man kann nicht die Zerstörung von Objekten selbst einleiten. Man kann maximal Ressourcen freigeben, indem man die Dispose-Methode, falls die Klasse IDisposable implementiert, aufruft. Das Objekt wird hierbei nicht zerstört.

Ein wesentlicher Unterschied ist: Bei einem herkömmlichen Destruktor sind alle Referenzen in der Klasse noch gültig, denn Kindobjekte werden erst später freigegeben. Bei einem Finalizer sind die Kindobjekte aber möglicherweise schon zerstört worden, soweit sie gemanaged sind.
Darüberhinaus ist es anders als z.B. in C++, wo jede Klasse einen Destruktor hat (gegebenenfalls vom Compiler generiert), in .net eine aufwändige Sache, einen Finalizer auszuführen und somit generell zu vermeiden.




Edit:
Zitat:
Man fügt keine Strings mit dem + zeichen zusammen, denn es wird dann eine neue Instanz mit diesem String pro + erzuegt, was somit langsam und speicherlastig ist. Der Garbace Collector wird zwar diesen Speicher wieder freigeben, jedoch liegt er zeitweise unnötig auf dem Heap herum.
Das stimmt generell, aber Luckie hat das mit const-Strings gemacht. Ein Blick in ildasm zeigt, dass die Objekte wirklich const sind, es wird also nicht pro + eine Instanz erzeugt, sondern nur pro Konstante - also genau das, was man will. Darüberhinaus ist der Garbage Collector gerade für kurzlebige, also z.B. temporäre Objekte optimiert.
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
  Mit Zitat antworten Zitat