Nas minhas aulas, implemento IDisposable da seguinte maneira:
public class User : IDisposable
{
public int id { get; protected set; }
public string name { get; protected set; }
public string pass { get; protected set; }
public User(int UserID)
{
id = UserID;
}
public User(string Username, string Password)
{
name = Username;
pass = Password;
}
// Other functions go here...
public void Dispose()
{
// Clear all property values that maybe have been set
// when the class was instantiated
id = 0;
name = String.Empty;
pass = String.Empty;
}
}
No VS2012, minha análise de código diz para implementar IDisposable corretamente, mas não tenho certeza do que fiz de errado aqui.
O texto exato é o seguinte:
CA1063 Implementar IDisposable corretamente Forneça uma implementação substituível de Dispose (bool) em 'User' ou marque o tipo como lacrado. Uma chamada para Dispose (false) deve limpar apenas os recursos nativos. Uma chamada para Dispose (true) deve limpar os recursos gerenciados e nativos. stman User.cs 10
Para referência: CA1063: Implementar IDisposable corretamente
Eu li esta página, mas tenho medo de não entender o que precisa ser feito aqui.
Se alguém puder explicar em termos mais lânguidos qual é o problema e / ou como o IDisposable deve ser implementado, isso realmente ajudará!
Dispose
?IDispoable
se tiver recursos não gerenciados para descarte (isso inclui recursos não gerenciados que são agrupados (SqlConnection
,FileStream
etc.). Você não deve nem deve implementarIDisposable
se tiver apenas recursos gerenciados como aqui. . um grande problema com a análise de código é muito bom em verificar bobo pequenas regras, mas não bom em verificação de erros conceituais.Respostas:
Essa seria a implementação correta, embora eu não veja nada que você precise descartar no código publicado. Você só precisa implementar
IDisposable
quando:Nada no código que você postou precisa ser descartado.
fonte
using(){ }
sempre que possível, mas para fazer isso, você precisa implementar o IDisposable; portanto, em geral, prefiro acessar uma classe usando usings, esp. se eu só precisa da classe em uma ou duas funçõesusing
bloco quando a classe implementar IDisposable . Se você não precisa que uma classe seja descartável, não a implemente. Não serve para nada.using
bloco tende a ser atraente além daIDisposable
interface sozinha. Imagino que tenha havido mais do que alguns abusosIDisposable
apenas para fins de escopo.GC.SuppressFinalize(this);
é inútil. Como o @mariozski apontou, um finalizador ajudaria a garantir que issoDispose
seja chamado se a classe não for usada dentro de umusing
bloco.Primeiro de tudo, você não precisa de "clean up"
string
s eint
s - eles vão ser realizado automaticamente pelo coletor de lixo. A única coisa que precisa ser limpaDispose
são recursos não gerenciados ou recursos gerenciados implementadosIDisposable
.No entanto, supondo que este seja apenas um exercício de aprendizado, a maneira recomendada de implementar
IDisposable
é adicionar uma "trava de segurança" para garantir que nenhum recurso seja descartado duas vezes:fonte
readonly
semântica)O exemplo a seguir mostra as melhores práticas gerais para implementar a
IDisposable
interface. ReferênciaLembre-se de que você precisa de um destruidor (finalizador) apenas se tiver recursos não gerenciados em sua classe. E se você adicionar um destruidor, suprimir Finalização em Dispor , caso contrário, os objetos residirão na memória por dois ciclos de lixo (Nota: Leia como a Finalização funciona ). Abaixo o exemplo elaborado acima.
fonte
IDisposable
existe para fornecer um meio para você limpar recursos não gerenciados que não serão limpos automaticamente pelo Garbage Collector.Todos os recursos que você está "limpando" são recursos gerenciados e, como tal, seu
Dispose
método não está conseguindo nada. Sua classe não deve implementarIDisposable
nada. O Garbage Collector cuidará de todos esses campos por conta própria.fonte
Você precisa usar o padrão descartável como este:
fonte
SafeHandle
(e subtipos). No caso de recursos gerenciados, implementar o descarte adequado se torna muito mais simples; você pode reduzir o código para uma implementação simples dovoid Dispose()
métodoVocê não precisa fazer sua
User
classe,IDisposable
pois a classe não adquire nenhum recurso não gerenciado (arquivo, conexão com o banco de dados etc.). Normalmente, marcamos as classes comoIDisposable
se tivessem pelo menos umIDisposable
campo ou propriedade. Ao implementarIDisposable
, é melhor colocá-lo de acordo com o esquema típico da Microsoft:fonte
Idisposable é implementado sempre que você deseja uma coleta de lixo determinística (confirmada).
Ao criar e usar a classe Users, use o bloco "using" para evitar chamar explicitamente o método de descarte:
O fim do objeto Users criado pelo bloco using será descartado pelo método implícito de invocação de disposição.
fonte
Eu vejo muitos exemplos do padrão Microsoft Dispose, que é realmente um anti-padrão. Como muitos apontaram, o código na pergunta não requer IDisposable. Mas se você for implementá-lo, não use o padrão da Microsoft. Melhor resposta seria seguir as sugestões deste artigo:
https://www.codeproject.com/Articles/29534/IDisposable-What-Your-Mother-Never-Told-You-About
A única outra coisa que provavelmente seria útil é suprimir esse aviso de análise de código ... https://docs.microsoft.com/en-us/visualstudio/code-quality/in-source-suppression-overview?view=vs- 2017
fonte