Cosa significa la tilde prima del nome di una funzione in C #?


164

Sto guardando un po 'di codice e ha questa affermazione:

~ConnectionManager()
{
    Dispose(false);
}

La classe implementa l' IDisposableinterfaccia, ma non so se questo fa parte della tilde (~).

Risposte:


213

~ è il distruttore

  1. I distruttori vengono invocati automaticamente e non possono essere richiamati in modo esplicito.
  2. I distruttori non possono essere sovraccaricati. Pertanto, una classe può avere al massimo un distruttore.
  3. I distruttori non sono ereditati. Pertanto, una classe non ha distruttori diversi da quello che può essere dichiarato in essa.
  4. I distruttori non possono essere usati con le strutture. Sono usati solo con le classi. Un'istanza diventa idonea alla distruzione quando non è più possibile per nessun codice utilizzare l'istanza.
  5. L'esecuzione del distruttore per l'istanza può avvenire in qualsiasi momento dopo che l'istanza diventa ammissibile alla distruzione.
  6. Quando un'istanza viene distrutta, i distruttori nella sua catena di eredità vengono chiamati, in ordine, dalla maggior parte derivata alla meno derivata.

Finalizza

In C #, il metodo Finalize esegue le operazioni che farebbe un distruttore C ++ standard. In C # non lo si chiama Finalizza: si utilizza la sintassi del distruttore C ++ per posizionare un simbolo tilde (~) prima del nome della classe.

Smaltire

È preferibile disporre di oggetti in un metodo Close()o Dispose()che può essere chiamato in modo esplicito dall'utente della classe. Finalize (destructor) sono chiamati dal GC.

L' interfaccia IDisposable dice al mondo che la tua classe tiene in mano risorse che devono essere smaltite e offre agli utenti un modo per rilasciarle. Se è necessario implementare un finalizzatore nella propria classe, il metodo Dispose deve utilizzare il GC.SuppressFinalize()metodo per assicurarsi che la finalizzazione dell'istanza venga soppressa.

Cosa usare?

Non è legale chiamare esplicitamente un distruttore. Il distruttore verrà chiamato dal garbage collector. Se si gestiscono preziose risorse non gestite (come gli handle di file) che si desidera chiudere e smaltire il più rapidamente possibile, è necessario implementare l'interfaccia IDisposable.


3
Non so come fosse in passato. Ma ora i distruttori sono ereditati. Controllare questo link per ulteriori informazioni (controllare l'esempio alla fine): msdn.microsoft.com/en-us/library/66x5fx1b.aspx
RononDex

1
@RononDex il punto 3 della stessa pagina che colleghi agli stati "I finalizzatori non possono essere ereditati" , il che contraddice il tuo commento. È certamente un po 'confuso perché, sebbene non possano essere ereditati, "il Finalizemetodo viene chiamato in modo ricorsivo per tutte le istanze nella catena dell'ereditarietà, dal più derivato al meno derivato" . Nota che non è lo stesso comportamento che potresti avere dai distruttori ereditabili.
Mark Amery,

@MarkAmery ah, vedo, quindi sostanzialmente vengono chiamati in ordine inverso rispetto a qualcosa che viene ereditato?
RononDex,

45

Questo è un finalizzatore . Ad essere onesti, dovresti raramente scrivere un finalizzatore. Devi solo scriverne uno se:

  • Hai accesso diretto a una risorsa non gestita (ad es. Tramite un IntPtr) e non puoi utilizzarlo per SafeHandlerenderlo più semplice
  • Stai implementando IDisposablein una classe che non è sigillata. (La mia preferenza è quella di sigillare le classi a meno che non siano progettate per l'ereditarietà). In questi casi, un finalizzatore fa parte del modello di smaltimento canonico.

9

È usato per indicare il distruttore per la classe.


12
Sono entrambi corretti, a seconda delle specifiche C # che leggi. Il più recente MS (unificato C # 3.0) si riferisce a loro come distruttori (ad es. Sezione 10.13) ma le specifiche ECMA si riferiscono a loro come finalizzatori.
Jon Skeet,

@ 1800INFORMATION: l' elemento sintattico viene correttamente chiamato distruttore. Se una classe ha un distruttore, un compilatore C # genererà automaticamente un finalizzatore che include un try/finallyblocco generalmente inutile che assicura che Finalizevenga chiamato il metodo parent . Molte cose vere per i distruttori sono vere per i finalizzatori e viceversa, ma le parole significano cose leggermente diverse.
supercat

4

Come C ++, è il distruttore; tuttavia in C # non lo si chiama esplicitamente, viene invocato quando l'oggetto viene raccolto.



Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.