Question

Je suis en train de travailler sur un projet OSS pour faire de la populaire MediaInfo bibliothèque plus simple d'utilisation .NET, mais cette question est généralisable.

Si une classe dérivée D toujours instancie un objet O lors de l'appel de sa classe de base DBs 'constructeur.DB définit sa valeur à celle envoyée à son constructeur, mais la valeur elle-même est déclaré dans DB's de la classe de base B:

  1. Le "propriétaire" O (AKA mediaInfo dans le code ci-dessous)?
  2. Dans le cas d'un .NET application, qui devrait mettre en œuvre IDisposable?Note: O n'est pas géré, ou, au moins, est une instanciation d'un objet géré enroulé autour d'un non géré la bibliothèque, mais a besoin de nettoyage sous la forme de "MediaInfo.Close();".Je ne suis pas certain de ce qui est considéré comme "non géré."

Pour aider à clarifier, permettez-moi d'utiliser code:

D dérive de DB:

// MediaFile is "D" 
public sealed class MediaFile : GeneralStream
{
    public MediaFile(string filePath)
        : base(new MediaInfo(), 0) {
        // mediaInfo is "O"
        mediaInfo.Open(filePath);
    }
}

DB définit sa hérité O, dérivé de B:

// GeneralStream is "DB"
public abstract class GeneralStream : StreamBaseClass
{
    public GeneralStream(MediaInfo mediaInfo, int id) {
        this.mediaInfo = mediaInfo; // declared in StreamBaseClass
        // ...
    }
}

B déclare O:

// StreamBaseClass is "B"
public abstract class StreamBaseClass
{
    protected MediaInfo mediaInfo; // "O" is declared
    // ...
}
Était-ce utile?

La solution

L'objet, qui contient une référence à la ressource, en est le propriétaire.

StreamBaseClass a la référence mediaInfo et mettre en œuvre IDisposable.La référence et la Dispose la méthode sera automatiquement héritée par l'dérivant des classes.

Autres conseils

Si une classe C est propriétaire d'une variable qui est une variable locale non exposée qui implémente Idisposable, alors c doit être iDisposable et c est Idisposable de C devraient disposer de v.

Si une classe D est propriétaire d'une ressource native N, DI devriez être iDisposable (qui supprime N) et doit également avoir un destructeur final qui appelle () sur lui-même pour libérer N.

Si vous suivez ce modèle, alors si vous avez déjà une opacité, vous devriez toujours disposer () le supprimer lorsque vous avez terminé et que vous supprimez tout tout en bas de l'arborescence de l'objet;Mais aussi si quelqu'un vous oublie (lire: un collègue, l'utilisateur de votre bibliothèque, etc.) ne fuit aucun objet car la ressource native sera nettoyée par Durizer.

La responsabilité d'une IDisposable appartient à l'objet que crée c', en l'absence de tout accord explicite contraire.Les accords sont généralement utilisés dans les cas où le créateur d'une ressource peut avoir aucune idée de la durée de vie du consommateur.Je voudrais suggérer que, dans de nombreux cas, lorsqu'un constructeur ou à l'usine, la méthode est la production de ce que peut être le dernier consommateur d'un passé- IDisposable, cette méthode doit accepter un paramètre indiquant si elle doit accepter la responsabilité de l'appelant Dispose, ou bien accepter un délégué de rappel qui, si elle est non nulle, être invoquée lorsque le consommateur n'a plus besoin de l'objet.Si le créateur de l'objet va survivre à la consommation, il peut passer null;si le créateur n'aura pas d'utilisation de l'objet une fois qu'il a été transmis, il peut passer de l'objet Dispose la méthode.Si le créateur ne sait pas si il va survivre à la consommation, il peut passer d'une méthode qui permettra de déterminer si l'objet est toujours nécessaire et appel Dispose si pas.

En ce qui concerne votre cas particulier, la construction d'un IDisposable dans un enchaînés appel du constructeur est une recette pour les fuites de ressource (car il n'y a aucun moyen pour envelopper enchaîné constructeur appelle un essayez-enfin, un bloc).Si vous étiez en quelque sorte de les manipuler de façon sécuritaire (p. ex.à l'aide d'une méthode plutôt qu'une enchaîné constructeur, ou à l'aide d'un [threadstatic] hack), je dirais que, puisque le créateur de l'objet (la classe dérivée) va savoir la durée de vie du consommateur (la classe de base), de la propriété et de nettoyage de la responsabilité devrait rester avec l'objet de créateur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top