Wann sollte ich einen Destruktor erstellen?

Beispielsweise:

public class Person { public Person() { } ~Person() { } } 

Wann sollte ich manuell einen Destruktor erstellen? Wann mussten Sie einen Destruktor erstellen?

Solutions Collecting From Web of "Wann sollte ich einen Destruktor erstellen?"

Die C # -Sprache ruft diese “Destruktoren” auf, aber die meisten Leute nennen sie “Finalizer”, da dies ihr .NET-Name ist und sie die Verwirrung mit C ++ – Destruktoren (die ziemlich unterschiedlich sind) reduziert.

Wie IDisposable und Finalizer implementieren: 3 einfache Regeln

UPDATE: Diese Frage war das Thema meines Blogs im Mai 2015 . Danke für die tolle Frage! In dem Blog finden Sie eine lange Liste von Unwahrheiten, die die meisten Menschen über die Finalisierung glauben.

Wann sollte ich manuell einen Destruktor erstellen?

Fast nie.

In der Regel erstellt man nur einen Destruktor, wenn die class an einer teuren nicht verwalteten Ressource festhält, die bereinigt werden muss, wenn das Objekt verschwindet. Es ist besser, das Einwegmuster zu verwenden, um sicherzustellen, dass die Ressource bereinigt wird. Ein Destruktor ist dann im Wesentlichen eine Versicherung, dass, wenn der Verbraucher Ihres Objekts vergisst, sie zu entsorgen, die Ressource immer noch aufgeräumt wird. (Könnte sein.)

Wenn Sie einen Destruktor erstellen, seien Sie äußerst vorsichtig und verstehen Sie, wie der Garbage Collector funktioniert . Destruktoren sind wirklich seltsam :

  • Sie laufen nicht auf deinem Thread; Sie laufen auf ihrem eigenen Thread. Verursachen Sie keine Deadlocks!
  • Eine unbehandelte Ausnahme, die von einem Destruktor geworfen wird, ist eine schlechte Nachricht. Es ist auf einem eigenen Thread; Wer wird es fangen?
  • Ein Destruktor kann für ein Objekt aufgerufen werden, nachdem der Konstruktor gestartet wurde, aber bevor der Konstruktor beendet wird. Ein ordnungsgemäß geschriebener Destruktor wird nicht auf Invarianten basieren, die im Konstruktor festgelegt sind.
  • Ein Destruktor kann ein Objekt “wiederbeleben”, wodurch ein toter Gegenstand wieder lebendig wird. Das ist wirklich komisch. Tu es nicht.
  • Ein Destruktor wird möglicherweise nie ausgeführt. Sie können sich nicht darauf verlassen, dass das Objekt zur Finalisierung geplant wird. Es wird wahrscheinlich sein, aber das ist keine Garantie.

Fast alles, was normalerweise wahr ist, ist in einem Destruktor wahr. Sei wirklich sehr, sehr vorsichtig. Das Schreiben eines korrekten Destruktors ist sehr schwierig.

Wann mussten Sie einen Destruktor erstellen?

Beim Testen des Teils des Compilers, der Destruktoren verarbeitet. Ich musste das nie im Produktionscode tun. Ich schreibe selten Objekte, die nicht verwaltete Ressourcen manipulieren.

Es heißt “Finalizer”, und Sie sollten normalerweise nur einen für eine class erstellen, deren Status (dh Felder) nicht verwaltete Ressourcen enthält (dh pointers auf Handles, die über p / invoke-Aufrufe abgerufen werden). In .NET 2.0 und höher gibt es jedoch eine bessere Möglichkeit, mit der Bereinigung nicht verwalteter Ressourcen umzugehen : SafeHandle . Angesichts dieser Tatsache sollten Sie nie wieder einen Finalizer schreiben müssen.

Sie benötigen keinen, es sei denn, Ihre class verwaltet nicht verwaltete Ressourcen wie Windows-Dateihandles.

Es heißt Destruktor / Finalizer und wird normalerweise beim Implementieren des Disposed-Musters erstellt.

Es ist eine Ausweichlösung, wenn der Benutzer Ihrer class vergessen hat, Dispose aufzurufen, um sicherzustellen, dass (eventuell) Ihre Ressourcen freigegeben werden, Sie jedoch keine Garantie haben, wann der Destruktor aufgerufen wird.

In dieser Stapelüberlauffrage zeigt die akzeptierte Antwort korrekt an, wie das Dispose-Muster implementiert wird. Dies ist nur erforderlich, wenn Ihre class nicht verwaltete Ressourcen enthält, die der Garbage Collector nicht selbst bereinigen kann.

Es empfiehlt sich, einen Finalizer nicht zu implementieren, ohne dem Benutzer der class die Möglichkeit zu geben, das Objekt manuell zu disponieren, um die Ressourcen sofort freizugeben.

Wenn Sie über nicht verwaltete Ressourcen verfügen, müssen Sie sicherstellen, dass sie bereinigt werden, wenn Ihr Objekt gelöscht wird. Ein gutes Beispiel wären COM-Objekte oder Dateihandler.

Ich habe einen Destruktor (nur für Debugzwecke) verwendet, um festzustellen, ob ein Objekt im Rahmen einer WPF-Anwendung aus dem Speicher gelöscht wurde. Ich war mir nicht sicher, ob die Speicherbereinigung wirklich das Objekt aus dem Speicher löschte, und dies war eine gute Möglichkeit, dies zu überprüfen.

Destruktoren bieten eine implizite Möglichkeit, nicht verwaltete Ressourcen zu befreien, die in Ihrer class eingekapselt sind. Sie werden aufgerufen, wenn der GC dazu gelangt, und sie rufen implizit die Finalize-Methode der Basisklasse auf. Wenn Sie viele nicht verwaltete Ressourcen verwenden, ist es besser, diese Ressourcen über die IDisposable-Schnittstelle explizit freizugeben. Weitere Informationen finden Sie im C # -Programmierhandbuch: http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx