Destruktor in C#



  • Hallo,
    Ich kenne bisher nur C++ und Java!

    Ich will nun in C# in einer Klasse eine statische Variable coden, welche sich erhöht bei erzeugen einer Isnstanz dieser Klasse! Die mach ich ja im Construktor Zähler++;......

    Nun meine FRage:

    Gibts in C# eine destruktor? und wie sieht der aus??



  • Desktruktoren gibt es in C# in C++-gewohnter Form nicht. Man kann Objekte auch nicht explizit löschen.
    Such mal die MSDN nach der Finalize-Methode ab.



  • ja das problem ist das ich die Instanzen eoiner Klasse zählen muss!! d.h. im konstruktor anzahl erhöhen und im Destruktor Anzahl vermindern



  • Es gibt auch in Java keinen C++-ähnlichen Destruktor, da du auf Grund der Garbage Collection keinen Einfluss darauf hast, wann eine Instanz tatsächlich freigegeben wird, dass ist in Java auch nicht anders!

    Es gibt nur, wie bereits geschrieben, Funktionen, die vom Garbage Collector aufgerufen werden, wenn dieser die Instanz tatsächlich freigibt. Diese sind aber nicht verlässlich genug, die genutzten Instanzen zu zählen! Auch wenn ein Objekt deiner Meinung nach nicht mehr genutz wird, kann es sein (und wird es auch oft sein), dass die Funktion noch lange nicht aufgerufen wird.



  • es geht:

    ~Klassename(){......}

    diese Method wird aufgrufen wenn das Objekt com GArbage Colle... zerstört wird.



  • BorisProgger schrieb:

    es geht:
    ~Klassename(){......}
    diese Method wird aufgrufen wenn das Objekt com GArbage Colle... zerstört wird.

    ALlerdinfgs kannst du nicht vorhersagen, wann der GC dein Objekt zerstört... was du brauchst ist eine automatische Freigabesemantik! In C# gibt es sowas ähnliches, aber nur explizit (lmao). Schau dir mal IDisposable und das using-Schlüsselwort an. Fazit: Mit C++/CLI geht sowas einfacher 😉 .



  • Auch wenn es schon (mehr oder minder) gesagt wurde, hier nochmal ein Zitat von ms:

    Destruktoren, im Prinzip wie bei C++, werden sie bei der Freigabe des Objekts aufgerufen. Es gibt aber einen wesentlichen Unterschied: Bei Klassenvariablen wird der Destruktor nicht aufgerufen, wenn die Variable ihre Gültigkeit verliert, sondern erst viel später, wenn die Garbage-Collection Speicher freigibt.
    Man sollte also in einem C#-Destruktor niemals Aktionen ausführen, die sofort ausgeführt werden müssen, etwa das Schließ;en einer Datei, die anschließ;end in einem anderen Objekt wieder geöffnet werden muss. Für solche Fälle ist es empfehlenswert, eine separate "Release"-Funktion zu definieren, die man am Ende explizit aufruft und die dann auch vom Destruktor sicherheitshalber auch noch einmal aufgerufen werden kann.
    Wie bei C++ haben auch bei C# Konstruktoren und Destruktoren keinen Rückgabewert.

    Quelle: Die Sprache C# im Detail



  • Die deutschen Übersetzungen von MS taugen nicht so wirklich. 😉 Zum Thema: In C# ist sowohl nicht-deterministische als auch deterministische Destruktion möglich, auch bei Exceptions und kompliziertem Kontrollfluss.

    Wer nicht weiß, wie man das macht, sollte folgendes lesen:
    http://msdn2.microsoft.com/en-us/library/fs2xkftw.aspx
    http://msdn2.microsoft.com/en-us/library/b1yfkh5e.aspx



  • Wo steht das? In deinen Links steht auch bloß die korrekte Implementation vom IDisposable Pattern, mehr nicht.



  • Ähm na gut. 😉 Deterministische Destruktion macht man mit try - finally. In den try-Block kommt der Code, der mit einer Resource arbeitet, in den finally-Block kommt der Code, der immer ausgeführt wird, sobald der try-Block verlassen wird:

    try {
        // böse viel resourcen benutzen
    }
    finally {
        // resourcen freigeben
        Console.Out.WriteLine("Wird immer ausgeführt.");
    }
    

    Das Freigeben der Resourcen sollte über die Dispose()-Methode erfolgen, siehe die Links von mir zum korrekten implementieren von Dispose().

    Ist der einzige Sinn des finally-Blocks das Aufrufen von Dispose(), kann das using-Statement verwendet werden:

    using( Image myImage = new Image(...) ) {
        // arbeiten mit dem Image
    }
    

    Das Image wird jetzt am Ende des Blocks automatisch disposed. Intern ist using nichts anderes als try - finally.

    Manche Klassen haben scheinbar kein Dispose(), sondern stattdessen Close() oder was anderes, wie die Stream-Klassen. Dieser Eindruck täuscht. Diese Klassen implementieren das Interface IDisposable explizit, so dass man nach IDisposable casten müsste, um Dispose() aufrufen zu können. Als "public" Variante steht dann Close() zur Verfügung. Trotzdem kann man auch solche Klassen mit dem using-Statement verwenden.


Log in to reply