Pregunta

Estoy trabajando en eso un proyecto OSS para hacer lo popular Biblioteca de información multimedia más fácil de usar en .NET, pero esta pregunta es generalizable.

Si una clase derivada D siempre crea una instancia de un objeto oh al llamar a su clase base DBEl constructor.DB establece su valor al enviado a su constructor, pero el valor en sí se declara en DBla clase base B:

  1. Quién posee" oh (También conocido como mediaInfo en el código siguiente)?
  2. En el caso de una aplicación .NET, ¿cuál de ellas debería implementar IDisposable?Nota: oh no está administrado, o al menos es una instancia de un objeto administrado envuelto alrededor de una biblioteca no administrada, pero necesita limpieza en forma de "MediaInfo.Close();".No estoy seguro de que esto cuente como "no administrado".

Para ayudar a aclarar, permítanme usar el código real:

D deriva 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 establece su herencia oh, derivado de B:

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

B declara oh:

// StreamBaseClass is "B"
public abstract class StreamBaseClass
{
    protected MediaInfo mediaInfo; // "O" is declared
    // ...
}
¿Fue útil?

Solución

El objeto que contiene una referencia al recurso es el propietario del mismo.

StreamBaseClass tiene la referencia mediaInfo y debería implementar IDisposable.La referencia y el Dispose El método será heredado automáticamente por las clases derivadas.

Otros consejos

Si una clase C posee una variable, que es una variable local no expuesta , que implementa Idisponesable, entonces C debe ser idisponerse y C's Idisponestable debe disponer v.

Si una clase D posee un recurso nativo n, entonces D debe ser iDisposición (que elimina N) y también debería tener un destructor finalizable que llama a disponer () en sí mismo para sumar n.

Si sigue este patrón, entonces, si alguna vez tiene un identificable, siempre debe desecharlo cuando haya terminado y eso eliminará todo por debajo del árbol de objetos;Pero también si alguien te olvida (lea: un colega, el usuario de su biblioteca, etc.) no fugas ningún objeto porque el recurso nativo se limpiará por el finalizador de D.

La responsabilidad de un IDisposable pertenece al objeto que crea ello, a falta de acuerdo explícito en contrario.Los acuerdos contrarios se utilizan generalmente en casos en los que el creador de un recurso puede no tener idea de la vida útil del consumidor.Sugeriría que en muchos casos, cuando un método constructor o de fábrica produce lo que puede ser el último consumidor de un método pasado IDisposable, ese método debe aceptar un parámetro que indique si debe aceptar la responsabilidad de llamar Dispose, o aceptar un delegado de devolución de llamada que, si no es nulo, se invocará cuando el consumidor ya no necesite el objeto.Si el creador del objeto sobrevive al consumidor, puede pasar nulo;Si el creador no va a utilizar el objeto una vez que se lo haya entregado, puede pasarle la propiedad. Dispose método.Si el creador no sabe si sobrevivirá al consumidor, puede pasar un método que determinará si el objeto todavía es necesario y llamar Dispose si no.

Con respecto a su caso particular, construir un IDisposable dentro de una llamada de constructor encadenada hay una receta para fugas de recursos (ya que no hay forma de envolver llamadas de constructor encadenadas en un bloque try-finally).Si de alguna manera pudieras manejar eso de manera segura (p. ej.usando un método de fábrica en lugar de un constructor encadenado, o usando un [threadstatic] hack), sugeriría que dado que el creador del objeto (la clase derivada) conocerá la vida útil del consumidor (la clase base), la propiedad y la responsabilidad de limpieza deben recaer en el creador del objeto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top