La mise en œuvre de IDisposable correctement
Dans mes classes, j'en œuvre 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 de mettre en œuvre IDisposable correctement, mais je ne suis pas sûr de ce que j'ai fait de mal ici.
Le texte exact est comme suit:
CA1063 mettre en Œuvre IDisposable Fournir correctement une substituables mise en œuvre de dispose(bool) sur "l'Utilisateur" ou la marque, le type scellé. Un appel à Disposer(faux) ne doit nettoyer ressources autochtones. Un appel à Disposer(true) permet de nettoyer à la fois réussi et ressources autochtones. stman de l'Utilisateur.cs 10
Pour référence: CA1063: mettre en Œuvre IDisposable correctement
J'ai lu cette page, mais j'ai peur de ne pas vraiment comprendre ce qui doit être fait ici.
Si quelqu'un peut expliquer plus en lamens termes quel est le problème et/ou comment IDisposable devraient être mises en œuvre, qui va vraiment aider!
- C'est que tout le code à l'intérieur de
Dispose
? - Avez-vous regarder l'exemple de code fourni dans le lien que vous avez posté?
- Il est le
IDisposable pattern
que vous devez utiliser / étudier. Je suis sûr que vous aurez beaucoup de réponses avec des détails bientôt, mais, fondamentalement, il consiste àGC.SupressFinalize()
et destructeur etc. - Vous devez mettre en œuvre votre méthode dispose() pour appeler la méthode dispose() sur l'un des membres de votre classe. Aucun de ces membres ont une. Vous devez donc pas mise en œuvre IDisposable. Réinitialiser les valeurs de propriété est inutile.
- Vous avez seulement besoin de mettre en œuvre
IDispoable
si vous avez des ressources non managées aliéner (cela inclut les ressources non managées sont enveloppés (SqlConnection
,FileStream
, etc.). Vous n'avez pas et ne devrait pas mise en œuvreIDisposable
si vous n'avez géré des ressources comme ici. C'est, IMO, un problème majeur avec l'analyse de code. Il est très bon à la vérification de silly peu de règles, mais pas très bon pour la vérification des erreurs conceptuelles. - C'est assez bouleversant pour moi que certaines personnes préfèrent downvote et de voir cette question fermée que de tenter d'aider une personne qui a mal compris un concept. Quelle honte.
- il y a déjà de matériels volumineux sur en ce qui concerne le modèle Jetable. Même dans les réponses à cette question, il y a de subtiles exemples de la mauvaise compréhension du modèle. Il est beaucoup mieux pour point d'avenir questionneurs de la première concerne DONC, la question (qui a 309 upvotes).
- Afin de ne pas downvote, ne pas upvote, laisser le poste à zéro et de fermer la question avec un utile pointeur.
Vous devez vous connecter pour publier un commentaire.
Ce serait la mise en œuvre correcte, bien que je ne vois pas de quoi vous jetez dans le code que vous avez posté. Vous avez seulement besoin de mettre en œuvre
IDisposable
lorsque:Rien dans le code que vous avez posté et doit être éliminée.
using(){ }
chaque fois que possible, mais pour ce faire, vous avez besoin pour mettre en œuvre IDisposable, donc en général, je préfère accéder à une classe par le biais de l'usage, de l'esp. si j'ai seulement besoin de la classe dans l'une ou les deux fonctionsusing
bloc lorsque la classe implémente IDisposable. Si vous n'avez pas besoin d'une classe pour être à usage unique, ne pas la mettre en œuvre. Il ne sert à rien.using
bloc ne ont tendance à être attrayante au-delà de laIDisposable
interface seuls, cependant. J'imagine qu'il ont été plus que un peu d'abus deIDisposable
juste pour les fins de la détermination de la portée.GC.SuppressFinalize(this);
est inutile. Comme @mariozski a souligné un finaliseur aiderait à assurez-vous que queDispose
est appelée à tous si la classe n'est pas utilisé à l'intérieur d'unusing
bloc.Tout d'abord, vous n'avez pas besoin de "nettoyer"
string
s etint
s - ils seront pris en charge automatiquement par le garbage collector. La seule chose qui a besoin d'être nettoyé dansDispose
sont des ressources non managées ou gérés autant de richesses que de mettre en œuvreIDisposable
.Cependant, en supposant que c'est juste un exercice d'apprentissage, la recommandé façon de mettre en œuvre
IDisposable
est d'ajouter un "cran de sécurité" pour s'assurer que toutes les ressources ne sont pas éliminés deux fois:readonly
sémantique)L'exemple suivant montre les meilleures pratiques à mettre en œuvre
IDisposable
interface. RéférenceGardez à l'esprit que vous avez besoin d'un destructeur(finaliseur) uniquement si vous avez les ressources non managées dans votre classe. Et si vous ajoutez un destructeur, vous devez supprimer la Finalisation dans les Disposer, sinon il va provoquer vos objets réside dans la mémoire pour les deux les cycles (Note: Lire comment la Finalisation de travaux). Ci-dessous un exemple d'élaborer tous les ci-dessus.
IDisposable
existe pour fournir un moyen pour vous de nettoyer non géré ressources qui ne seront pas nettoyés automatiquement par le Garbage Collector.Toutes les ressources qui vous sont "nettoyage" du sont gérées les ressources, et en tant que tel votre
Dispose
méthode est de ne rien accomplir. Votre classe ne devrait pas mettre en œuvreIDisposable
à tous. Le Garbage Collector de prendre soin de tous ces champs très bien sur son propre.Vous devez utiliser le Jetables Modèle comme ceci:
SafeHandle
(et sous-types). Dans le cas de la gestion des ressources la mise en œuvre de l'élimination appropriée devient beaucoup plus simple; vous pouvez découper le code en bas d'une simple mise en œuvre de lavoid Dispose()
méthode.Vous n'avez pas besoin de faire votre
User
classeIDisposable
depuis la classe ne pas acquérir non géré les ressources (fichiers, base de données de connexion, etc.). Généralement, on marque les classesIDisposable
si ils ont au moins unIDisposable
terrain ou/et de la propriété.Lors de la mise en œuvre de
IDisposable
, pour mieux dire, selon Microsoft modèle typique:Idisposable est de mettre en œuvre chaque fois que vous voulez un déterministe (confirmé) collecte des ordures.
Lors de la création et de l'aide aux Utilisateurs de la classe d'usage "à l'aide de" bloquer pour éviter d'appeler explicitement la méthode dispose:
fin de l'aide du bloc de créer des Utilisateurs de l'objet seront éliminés par implicite invoquer de la méthode dispose.
Je vois beaucoup d'exemples de Microsoft modèle dispose ce qui est vraiment un anti-modèle. Comme beaucoup l'ont souligné, le code en question ne nécessite pas IDisposable à tous. Mais si vous où va le mettre en œuvre s'il vous plaît ne pas utiliser le patron de Microsoft. Meilleure réponse serait de suivre les conseils dans cet article:
https://www.codeproject.com/Articles/29534/IDisposable-What-Your-Mother-Never-Told-You-About
La seule autre chose qui serait susceptible d'être utile est la suppression que l'analyse du code d'avertissement... https://docs.microsoft.com/en-us/visualstudio/code-quality/in-source-suppression-overview?view=vs-2017