2016-05-31 2 views
1

J'ai écrit une classe qui hérite de DbConnection et je ne comprends pas complètement pourquoi elle fonctionne comme elle le fait.Pourquoi ai-je besoin d'implémenter IDisposable() sur une classe enfant

Au début, j'eu ceci:

public class DatabaseConnection : DbConnection 
{ 
    ... 
    public override void Close() 
    { 
     // Some stuff 
    } 
    // No Dispose method 
} 

using(var db = new DatabaseConnection()) 
{ 
    // Some processing 
} 

La méthode Close() n'a pas été appelé, et nous avons pu voir les connexions rester sur le serveur MySQL.


Maintenant, j'ai cela, et il fonctionne (il ferme vraiment les connexions, et le serveur est OK):

public class DatabaseConnection : DbConnection, IDisposable 
{ 
    ... 
    public override void Close() 
    { 
     // Some stuff 
    } 

    public new void Dispose() 
    { 
     Close(); 
     base.Dispose(); 
     GC.SuppressFinalize(this); 
    } 
} 

using(var db = new DatabaseConnection()) 
{ 
    // Some processing 
} 

Pourquoi héritant de la classe DbConnection et en remplaçant la Fermer La méthode() ne fonctionne pas?

+0

Éliminer ou fermer? Parce que le contenu de la méthode Dispose est déjà là –

Répondre

1

Vous pouvez voir dans le reference source que DbConnection ne l'emporte pas sur Dispose, donc Dispose n'appellera Close.

DbConnection hérite de Component, où est l'implémentation de IDisposable. Vous pouvez voir la reference source que sa méthode est Dispose(bool disposing)virtual, vous devriez donc passer outre que:

protected override void Dispose(bool disposing) 
{ 
    base.Dispose(disposing) 
    Close(); 
} 
+0

Certains pourraient argumenter qu'il y a un "bug" dans 'DbConnection', ou au moins dans sa [documentation] (https://msdn.microsoft.com/fr-fr/library /system.data.common.dbconnection.close(v=vs.110).aspx): "... ferme la connexion en appelant' Close' ou 'Dispose', qui sont fonctionnellement équivalents." - mais comme nous l'avons vu, il n'y a aucune garantie que les classes héritées maintiendront cette équivalence de fonction, alors qu'elle aurait pu l'être facilement (en ayant au moins une "note aux héritiers" ou en codant explicitement cette co-dépendance). –

+0

Merci, je vois la logique là-bas. C'est très confus avec toutes les questions comme [this] (http://stackoverflow.com/questions/5243398/will-a-using-block-close-a-database-connection) montrant un simple using()! –

+0

@MickaelV. c'est particulièrement déroutant car (comme le souligne Damien) la documentation dit que ça marche aussi. Le commentaire sur la réponse à votre question liée est valide, cependant: * En pratique, je doute qu'il existe des implémentations DBConnection qui ne remplacent pas Dispose et ferment toutes les connexions *. Vous remarquez seulement cela parce que vous héritez de la classe de base. –

0

Le using statement appelle la méthode Dispose à la fin du bloc. Comme le DbConnection implémente également l'interface IDisposable, le bloc using dans le premier extrait appelle la méthode Dispose héritée.

La connexion reste active peut-être parce que vous remplacez la fonction Fermer, mais je ne suis pas sûr de cela, veuillez me corriger si je me trompe.