Dans mes classes, j'implémente IDisposable comme suit:
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;
}
}
Dans VS2012, mon analyse de code dit d'implémenter correctement IDisposable, mais je ne suis pas sûr de ce que j'ai fait de mal ici.
Le texte exact est le suivant:
CA1063 Implémenter correctement IDisposable Fournit une implémentation remplaçable de Dispose (bool) sur 'User' ou marque le type comme scellé. Un appel à Dispose (false) ne doit nettoyer que les ressources natives. Un appel à Dispose (true) doit nettoyer les ressources gérées et natives. stman User.cs 10
Pour référence: CA1063: implémenter correctement IDisposable
J'ai lu cette page, mais j'ai bien peur de ne pas vraiment comprendre ce qui doit être fait ici.
Si quelqu'un peut expliquer en termes plus simples quel est le problème et / ou comment IDisposable doit être implémenté, cela aidera vraiment!
Dispose
?IDispoable
si vous avez des ressources non gérés à disposer de (ce qui inclut les ressources non gérés qui sont enveloppées (SqlConnection
,FileStream
, etc.). Vous ne et ne devrait pas mettre en œuvreIDisposable
si vous n'avez réussi ressources comme ici. Ceci est, l' OMI, un problème majeur avec l'analyse de code. Il est très bon pour vérifier les petites règles stupides, mais pas bon pour vérifier les erreurs conceptuelles.Réponses:
Ce serait l'implémentation correcte, même si je ne vois rien dont vous avez besoin pour disposer dans le code que vous avez publié. Vous ne devez mettre en œuvre que
IDisposable
lorsque:Rien dans le code que vous avez publié ne doit être supprimé.
la source
using(){ }
autant que possible, mais pour ce faire, vous devez implémenter IDisposable, donc en général, je préfère accéder à une classe via des utilisations, en particulier. si je n'ai besoin que du cours dans une ou deux fonctionsusing
bloc lorsque la classe implémente IDisposable . Si vous n'avez pas besoin qu'une classe soit jetable, ne l'implémentez pas. Cela ne sert à rien.using
bloc a tendance à être attrayante au-delà de l'IDisposable
interface seule, cependant. J'imagine qu'il y a eu plus que quelques abusIDisposable
juste à des fins de cadrage.GC.SuppressFinalize(this);
est inutile. Comme @mariozski l'a souligné, un finaliseur aiderait à s'assurer qu'ilDispose
est appelé du tout si la classe n'est pas utilisée dans unusing
bloc.Tout d'abord, vous n'avez pas besoin de "nettoyer" les
string
s etint
s - ils seront automatiquement pris en charge par le ramasse-miettes. La seule chose qui doit être nettoyéeDispose
est les ressources non gérées ou les ressources gérées qui implémententIDisposable
.Cependant, en supposant qu'il ne s'agisse que d'un exercice d'apprentissage, la méthode recommandée pour l'implémentation
IDisposable
est d'ajouter un «cran de sécurité» pour s'assurer que les ressources ne sont pas éliminées deux fois:la source
readonly
sémantique)L'exemple suivant montre les meilleures pratiques générales pour implémenter l'
IDisposable
interface. RéférenceGardez à l'esprit que vous n'avez besoin d'un destructeur (finaliseur) que si vous avez des ressources non gérées dans votre classe. Et si vous ajoutez un destructeur, vous devez supprimer la finalisation dans le Dispose , sinon vos objets résideront en mémoire pendant deux cycles de garbage (Remarque: lisez comment la finalisation fonctionne ). L'exemple ci-dessous explique tout ce qui précède.
la source
IDisposable
existe pour vous fournir un moyen de nettoyer les ressources non gérées qui ne seront pas nettoyées automatiquement par le garbage collector.Toutes les ressources que vous «nettoyez» sont des ressources gérées et, en tant que telles, votre
Dispose
méthode ne fait rien. Votre classe ne devrait pas du tout implémenterIDisposable
. Le garbage collector s'occupera très bien de tous ces champs tout seul.la source
Vous devez utiliser le modèle jetable comme ceci:
la source
SafeHandle
(et sous-types). Dans le cas de ressources gérées, la mise en œuvre d'une élimination appropriée devient beaucoup plus simple; vous pouvez réduire le code à une implémentation simple de lavoid Dispose()
méthode.Vous n'avez pas besoin de faire votre
User
classe étantIDisposable
donné que la classe n'acquiert aucune ressource non gérée (fichier, connexion à la base de données, etc.). Habituellement, nous marquons les classes commeIDisposable
si elles avaient au moins unIDisposable
champ ou / et une propriété. Lors de la mise en œuvreIDisposable
, mieux vaut le mettre selon le schéma typique de Microsoft:la source
Idisposable est implémenté chaque fois que vous souhaitez un garbage collection déterministe (confirmé).
Lors de la création et de l'utilisation de la classe Users, utilisez le bloc "using" pour éviter d'appeler explicitement la méthode dispose:
La fin de l'objet Users créé par le bloc using sera supprimée par un appel implicite de la méthode dispose.
la source
Je vois beaucoup d'exemples du modèle Microsoft Dispose qui est vraiment un anti-modèle. Comme beaucoup l'ont souligné, le code de la question ne nécessite pas du tout d'IDisposable. Mais si vous souhaitez l'implémenter, n'utilisez pas le modèle Microsoft. Une meilleure réponse serait de suivre les suggestions de cet article:
https://www.codeproject.com/Articles/29534/IDisposable-What-Your-Mother-Never-Told-You-About
La seule autre chose qui serait probablement utile est de supprimer cet avertissement d'analyse de code ... https://docs.microsoft.com/en-us/visualstudio/code-quality/in-source-suppression-overview?view=vs- 2017
la source