J'ai une classe abstraite qui implémente Idisposable, comme:
public abstract class ConnectionAccessor : IDisposable { public abstract void Dispose(); }
5 Réponses :
L'avertissement vous indique essentiellement de mettre en œuvre le Dispose modèle fort > dans votre classe.
Le code résultant devrait ressembler à ceci: p>
+1 Pour mentionner le motif, et soulignant que le dispositif d'élimination (BOOL) doit être la méthode virtuelle / abstrait que les classes dérivées doivent être appliquées ou remplacées, ne pas disposer ().
Vous devez suivre le modèle classique pour la mise en œuvre clé ici est qu'il n'y a pas de duplication entre le finaliseur et le Pour votre cas, ce que vous devriez faire est celui-ci: p> et laisser tout le reste tel quel. Même cela est de valeur douteuse, car vous appliquez vos classes dérivées pour mettre en œuvre Disposer code>. Rendre
Dispose () code> Virtual est considéré comme une mauvaise pratique, car le motif conventionnel met l'accent sur la réutilisation du code dans "Nettoyage géré" (Calling client API
Dispose () code> directement ou via
en utilisant code>) et "nettoyage non géré" (finisseur d'appel GC). Pour rappeler, le motif est-ce:
Dispose code> pour un nettoyage non géré, et pourtant toute classe dérivée peut prolonger les deux et nettoyage non géré. P>
Disposer code> maintenant - et comment savez-vous que tous en ont besoin? Si votre classe de base n'a rien à disposer, mais la plupart des classes dérivées sont probablement (à quelques exceptions près, peut-être), il suffit de fournir une implémentation vide. C'est ce que
system.io.io.stream code> (abstrait) est donc précédent. P> p>
Je préférerais beaucoup que les gens soient invités à faire cela: nitoprograms.blogspot.com/2009/08/... - Le modèle serait un enfer de beaucoup plus simple s'il n'avait pas de soutien intégré aux cours qui mixent les ressources gérées et non gérées.
Si une classe dérivée d'une classe particulière devra mettre en œuvre Idisposable, et si un objet qui s'attend à ce que le type de classe de base puisse finir de manière à contenir la dernière référence utile, la classe de base doit mettre en œuvre Idisposable, même si le vaste La majorité des classes dérivées n'en auront pas besoin.
Ce modèle n'est-il pas défendu depuis .net 2? Ma compréhension est que les ressources non gérées doivent être détenues par une certaine forme de la manipulation de SafeHandle / Critique et des classes normales d'utilisation des utilisateurs normaux n'ont plus besoin d'un finaliseur. Et leur Dispose code> Just Appels
Dispose code> sur la poignée.
L'avertissement est intéressant cependant. Eric LIPPERT, l'un des concepteurs C #, a blogué sur pourquoi les messages d'erreur devraient être "diagnostic mais pas prescriptif: décrivez le problème, pas la solution". lire ici . p>
Ce n'est pas un message d'erreur de compilateur. C'est le résultat de la gestion d'un outil qui indique spécifiquement des choses problématiques. Il n'y a rien de mal à souligner aussi la solution.
Sûr. Je voulais juste partager le lien. Il est venu à moi parce que le message n'indique pas le problème mais donne uniquement la solution. J'espère qu'il y avait un message précédent faisant cela.
C'est une sorte d'tangentielle à la question initiale.
Bien que cela semble un peu comme la cueillette de nit, le conseil est valide. Vous indiquez déjà que vous vous attendez à ce que les sous-types de Connectioncessor auront quelque chose em> qu'ils doivent disposer. Par conséquent, il semble préférable de s'assurer que le nettoyage approprié est effectué (en termes d'appel GC.SuppressFinalize) par la classe de base plutôt que de s'appuyer sur chaque sous-type pour le faire. J'utilise le modèle d'élimination mentionné dans Bruce Wagers Réservez efficace C # qui est fondamentalement: P> public class BaseClass : IDisposable
{
private bool _disposed = false;
~BaseClass()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(true);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
//release managed resources
}
//release unmanaged resources
_disposed = true;
}
}
public void Derived : BaseClass
{
private bool _disposed = false;
protected override void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
//release managed resources
}
//release unmanaged resources
base.Dispose(disposing);
_disposed = true;
}
La seule grille que j'aurais avec les réponses fournies jusqu'à présent, c'est qu'ils supposent tous que vous
Ma grpe préférée. La plupart des gens ne portent tout simplement pas la peine d'essayer de comprendre cela et le meilleur conseil qu'ils ont tendance à obtenir sont de simplement implémenter le modèle Microsoft. Voici ce que je pense, c'est un meilleur meilleur conseil que le modèle "officiel": Nitoprogramme.BlogOgspot.com/2009/08/...
C'est bien un bon article de blog sur le sujet - simple et aussi le point.
Pourquoi avez-vous besoin d'ajouter un dispositif () à votre interface? S'il est hérité de Idisposable, la méthode Dispose () fait déjà partie de votre interface.
Seth, vous devez mettre en œuvre tous les membres de l'interface. Le quitter ne compilerait pas.