Eu tenho uma classe simples como esta que implementa IDisposable
e é atingida por um CA1816: Call GC.SuppressFinalize corretamente :
public class A : IDisposable
{
// ...
int foo
public A()
{
SomeObj.SomeEvent += DoSomething;
}
public void Dispose()
{
SomeObj.SomeEvent -= DoSomething;
}
}
Altere A.Dispose() para chamar GC.SuppressFinalize(objeto). Isso evitará que tipos derivados que introduzem um finalizador precisem reimplementar 'IDisposable' para chamá-lo.
Agora eu li this , this e this mas ainda não entendi exatamente para que serve isso (mais explicações abaixo). Então minhas perguntas são :
Devo sempre adicionar algo
GC.SuppressFinalize(object)
ao meuDispose
método se não entender o que é?Quando NÃO devo fazer isso e apenas suprimir o aviso?
Para adicionar mais contexto: ainda não entendo o que SuppressFinalize
está acontecendo. Eu sei que já descartei alguns recursos Dispose
(manipuladores de eventos no exemplo, ou IDisposable
recursos etc.), mas e variáveis como int foo
essa ainda precisam ser limpas? E quanto à parte de aviso de "Isso impedirá que tipos derivados que introduzem um finalizador precisem ser reimplementados"?
Finalizador ou destruidor é um legado do C++, mas em C# estende o tempo que o GC leva para que os objetos sejam coletados.
Ao usar o padrão de descarte, você libera recursos manualmente (ou pela instrução using), os finalizadores não são mais necessários. O método
GC.SuppressFinalize
consiste em dizer ao GC para ignorar o finalizador do alvo e coletá-lo como um objeto normal, melhorando assim o desempenho do GC. Se você não chamar esse método, perderá o sentido de usar o padrão de descarte, por isso é uma boa prática sempre adicioná-lo.Sim, sua classe não possui finalizador, mas você não pode garantir que suas subclasses também não tenham. Observe que esta análise não será relatada em aulas lacradas (de acordo com meus testes, aulas internas/privadas também não serão).
Nunca deveria ser. Como mencionado acima, mesmo que você não ligue
GC.SuppressFinalize
, isso geralmente afeta apenas o desempenho. A menos que você libere recursos no método de descarte e no finalizador separadamente, mas parece que isso é algum tipo de erro de programação.