Was bedeutet die Tilde vor einem Funktionsnamen in C #?


164

Ich schaue mir einen Code an und er hat folgende Aussage:

~ConnectionManager()
{
    Dispose(false);
}

Die Klasse implementiert die IDisposableSchnittstelle, aber ich weiß nicht, ob dies ein Teil davon ist, für den die Tilde (~) verwendet wird.

Antworten:


213

~ ist der Destruktor

  1. Destruktoren werden automatisch aufgerufen und können nicht explizit aufgerufen werden.
  2. Destruktoren können nicht überladen werden. Somit kann eine Klasse höchstens einen Destruktor haben.
  3. Destruktoren werden nicht vererbt. Eine Klasse hat also keine anderen Destruktoren als die, die darin deklariert werden können.
  4. Destruktoren können nicht mit Strukturen verwendet werden. Sie werden nur mit Klassen verwendet. Eine Instanz kann zerstört werden, wenn kein Code mehr die Instanz verwenden kann.
  5. Die Ausführung des Destruktors für die Instanz kann jederzeit erfolgen, nachdem die Instanz zur Zerstörung berechtigt ist.
  6. Wenn eine Instanz zerstört wird, werden die Destruktoren in ihrer Vererbungskette in der Reihenfolge von am meisten abgeleitet bis am wenigsten abgeleitet aufgerufen.

Finalisieren

In C # führt die Finalize-Methode die Operationen aus, die ein Standard-C ++ - Destruktor ausführen würde. In C # nennen Sie es nicht Finalize - Sie verwenden die C ++ - Destruktorsyntax, um ein Tilde-Symbol (~) vor dem Namen der Klasse zu platzieren.

Entsorgen

Es ist vorzuziehen, Objekte in einer Close()oder Dispose()Methode zu entsorgen , die vom Benutzer der Klasse explizit aufgerufen werden kann. Finalize (Destruktor) werden vom GC aufgerufen.

Die IDisposable- Oberfläche teilt der Welt mit, dass Ihre Klasse über Ressourcen verfügt, die entsorgt werden müssen, und bietet Benutzern die Möglichkeit, diese freizugeben. Wenn Sie brauchen einen Finalizer in Ihrer Klasse zu implementieren, Ihre Dispose - Methode sollte die Verwendung GC.SuppressFinalize()Methode , um sicherzustellen , dass die Finalisierung Ihrer Instanz unterdrückt wird.

Was ist zu verwenden?

Es ist nicht legal, einen Destruktor explizit aufzurufen. Ihr Destruktor wird vom Garbage Collector aufgerufen. Wenn Sie wertvolle nicht verwaltete Ressourcen (z. B. Dateihandles) verarbeiten, die Sie schließen und so schnell wie möglich entsorgen möchten, sollten Sie die IDisposable-Schnittstelle implementieren.


3
Ich weiß nicht, wie es früher war. Aber jetzt werden Destruktoren geerbt. Überprüfen Sie diesen Link für weitere Informationen (überprüfen Sie das Beispiel am Ende): msdn.microsoft.com/en-us/library/66x5fx1b.aspx
RononDex

1
@RononDex Punkt 3 der Seite, auf die Sie verlinken, lautet "Finalizer können nicht vererbt werden" , was Ihrem Kommentar widerspricht. Es ist zugegebenermaßen alles etwas verwirrend, denn obwohl sie nicht vererbt werden können, "wird die FinalizeMethode für alle Instanzen in der Vererbungskette rekursiv aufgerufen, von den am meisten abgeleiteten bis zu den am wenigsten abgeleiteten" . Beachten Sie jedoch, dass dies nicht das gleiche Verhalten ist, das Sie von vererbbaren Destruktoren erhalten würden.
Mark Amery

@ MarkAmery ah, ich verstehe, also werden sie im Grunde genommen in umgekehrter Reihenfolge aufgerufen, verglichen mit etwas, das geerbt wird?
RononDex

45

Dies ist ein Finalizer . Um ehrlich zu sein, sollten Sie sehr selten einen Finalizer schreiben müssen. Sie müssen wirklich nur eine schreiben, wenn:

  • Sie haben direkten Zugriff auf eine nicht verwaltete Ressource (z. B. über eine IntPtr) und können diese nicht verwenden, SafeHandlewas die Arbeit erleichtert
  • Sie implementieren IDisposablein einer Klasse, die nicht versiegelt ist. (Ich bevorzuge es, Klassen zu versiegeln, es sei denn, sie sind für die Vererbung vorgesehen.) In solchen Fällen ist ein Finalizer Teil des kanonischen Entsorgungsmusters.

9

Es wird verwendet, um den Destruktor für die Klasse anzugeben.


12
Sie sind beide korrekt, je nachdem, welche C # -Spezifikation Sie gelesen haben. In der neuesten MS One (Unified C # 3.0) werden sie als Destruktoren bezeichnet (z. B. Abschnitt 10.13), in der ECMA-Spezifikation werden sie jedoch als Finalisierer bezeichnet.
Jon Skeet

@ 1800INFORMATION: Das syntaktische Element wird ordnungsgemäß als Destruktor bezeichnet. Wenn eine Klasse einen Destruktor hat, generiert ein C # -Compiler automatisch einen Finalizer, der einen allgemein nutzlosen try/finallyBlock enthält, der sicherstellt, dass die übergeordnete FinalizeMethode aufgerufen wird. Die meisten Dinge, die für Destruktoren gelten, gelten für Finalisierer und umgekehrt, aber die Wörter bedeuten etwas andere Dinge.
Supercat

4

Genau wie C ++ ist es der Destruktor. In C # wird es jedoch nicht explizit genannt. Es wird aufgerufen, wenn das Objekt gesammelt wird.



Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.