O que o til antes de um nome de função significa em C #?

164

Eu estou olhando para algum código e tem esta declaração:

~ConnectionManager()
{
    Dispose(false);
}

A classe implementa a IDisposableinterface, mas não sei se isso faz parte do qual o til (~) é usado.

Keith Sirmons
fonte

Respostas:

213

~ é o destruidor

  1. Os destruidores são invocados automaticamente e não podem ser invocados explicitamente.
  2. Destrutores não podem ser sobrecarregados. Assim, uma classe pode ter, no máximo, um destruidor.
  3. Destruidores não são herdados. Assim, uma classe não possui destruidores além daquele que pode ser declarado nela.
  4. Destrutores não podem ser usados ​​com estruturas. Eles são usados ​​apenas com classes. Uma instância se torna elegível para destruição quando não é mais possível que nenhum código use a instância.
  5. A execução do destruidor para a instância pode ocorrer a qualquer momento após a instância se tornar elegível para destruição.
  6. Quando uma instância é destruída, os destruidores em sua cadeia de herança são chamados, em ordem, do mais derivado para o menos derivado.

Finalizar

Em C #, o método Finalize executa as operações que um destruidor C ++ padrão faria. No C #, você não chama Finalize - você usa a sintaxe do destruidor C ++ para colocar um símbolo til (~) antes do nome da classe.

Descarte

É preferível descartar objetos em um método Close()ou Dispose()que possa ser chamado explicitamente pelo usuário da classe. Finalizar (destruidor) são chamados pelo GC.

A interface IDisposable informa ao mundo que sua classe mantém recursos que precisam ser descartados e fornece aos usuários uma maneira de liberá-los. Se você precisar implementar um finalizador em sua classe, seu método Dispose deverá usar o GC.SuppressFinalize()método para garantir que a finalização da sua instância seja suprimida.

O que usar?

Não é legal chamar explicitamente um destruidor. Seu destruidor será chamado pelo coletor de lixo. Se você manipular preciosos recursos não gerenciados (como identificadores de arquivo) dos quais deseja fechar e descartar o mais rápido possível, implemente a interface IDisposable.

Patrick Desjardins
fonte
3
Não sei como costumava ser no passado. Mas agora os destruidores são herdados. Verifique este link para obter mais informações (veja o exemplo no final): msdn.microsoft.com/en-us/library/66x5fx1b.aspx
RononDex
1
O @RononDex, ponto 3 da própria página que você vincula aos estados "Os finalizadores não podem ser herdados" , o que contradiz o seu comentário. É certo que tudo é um pouco confuso porque, embora não possam ser herdados "Finalize , o método é chamado recursivamente para todas as instâncias da cadeia de herança, da mais derivada à menos derivada" . Observe que esse não é o mesmo comportamento que você teria dos destruidores herdáveis.
Mark Amery
@ MarkAmery ah eu vejo, então basicamente eles são chamados na ordem inversa em comparação com algo que é herdado?
RononDex
45

Este é um finalizador . Para ser sincero, você raramente precisará escrever um finalizador. Você realmente só precisa escrever um se:

  • Você tem acesso direto a um recurso não gerenciado (por exemplo, através de um IntPtr) e não pode usar o SafeHandleque torna mais fácil
  • Você está implementando IDisposableem uma classe que não está selada. (Minha preferência é selar classes, a menos que elas sejam projetadas para herança.) Nesses casos, um finalizador faz parte do padrão canônico Dispose.
Jon Skeet
fonte
9

É usado para indicar o destruidor da classe.

histórico
fonte
12
Ambos estão corretos, dependendo da especificação de C # que você lê. O MS mais recente (C # 3.0 unificado) se refere a eles como destruidores (por exemplo, seção 10.13), mas a especificação da ECMA se refere a eles como finalizadores.
Jon Skeet
@ 1800INFORMAÇÃO: O elemento sintático é chamado apropriadamente de destruidor. Se uma classe tiver um destruidor, um compilador C # gerará automaticamente um finalizador que inclui um try/finallybloco geralmente inútil que garante que o Finalizemétodo pai seja chamado. A maioria das coisas verdadeiras para os destruidores é verdadeira para os finalizadores e vice-versa, mas as palavras significam coisas ligeiramente diferentes.
Supercat
4

O mesmo que C ++, é o destruidor; no entanto, em C # você não o chamou explicitamente, ele é chamado quando o objeto é coletado.

Santiago Palladino
fonte
3

Consulte Destrutores (Guia de programação em C #) . Esteja ciente, no entanto, que, diferentemente do C ++, o programador não tem controle sobre quando o destruidor é chamado, porque isso é determinado pelo coletor de lixo.

Jeff Stong
fonte
1

~ geralmente representa um desconstrutor. que é executado logo antes da morte de um objeto.

Aqui está uma descrição dos desconstrutores C # que encontrei

stephenbayer
fonte
4
o termo correto deve ser destruidor / finalizador, não desconstrutor. Desconstrutor significa uma sintaxe para desconstruir um construtor.
Eriawan Kusumawardhono