Tengo una pequeña jerarquía de objetos que, en general, se construye a partir de datos en un Stream
, pero para algunas subclases particulares, se pueden sintetizar a partir de una lista de argumentos más simple. Al encadenar a los constructores de las subclases, me encuentro con un problema para garantizar la eliminación de la secuencia sintetizada que necesita el constructor de la clase base. No se me escapó que el uso de objetos IDisposable
de esta manera es posiblemente solo un grupo sucio (¿por favor asesorar?) Por razones que no he considerado, pero, aparte de este tema, parece bastante sencillo (y una buena encapsulación).Pasar objetos identificables a través de las cadenas de constructores
Códigos:
abstract class Node {
protected Node (Stream raw)
{
// calculate/generate some base class properties
}
}
class FilesystemNode : Node {
public FilesystemNode (FileStream fs)
: base (fs)
{
// all good here; disposing of fs not our responsibility
}
}
class CompositeNode : Node {
public CompositeNode (IEnumerable some_stuff)
: base (GenerateRaw (some_stuff))
{
// rogue stream from GenerateRaw now loose in the wild!
}
static Stream GenerateRaw (IEnumerable some_stuff)
{
var content = new MemoryStream();
// molest elements of some_stuff into proper format, write to stream
content.Seek (0, SeekOrigin.Begin);
return content;
}
}
que darse cuenta de que no disponiendo de un MemoryStream
no es exactamente un caso de parada del mundo de mala ciudadanía CLR, pero todavía me pone los pelos de punta (por no mencionar que me permite no siempre usar un MemoryStream
para otros subtipos). No está en el alcance, así que no puedo explícitamente Dispose()
más tarde en el constructor, y agregar una declaración using
en GenerateRaw()
es contraproducente ya que necesito que se devuelva la ruta.
¿Hay una mejor manera de hacerlo?
ataques preventivos:
- sí, las propiedades calculadas en el
Node
constructor deben ser parte de la clase base, y no deben ser calculada por (o accesible en) las subclases - no lo haré requiere que una transmisión pase a CompositeNode (su formato debe ser irrelevante para la persona que llama)
- La iteración anterior tenía el cálculo del valor en la clase base como un método protegido independiente, que acabo de llamar al final de cada constructor de subtipo movió el cuerpo de
GenerateRaw()
a una usando instrucción en el cuerpo del constructorCompositeNode
. Pero la repetición de requerir esa llamada para cada constructor y no poder garantizar que se ejecute para cada subtipo (unNode
no es unNode
, semánticamente, sin estas propiedades inicializadas) me dio heebie-jeebies mucho peor que el (potencial) la fuga de recursos aquí sí.
sé que esto es una vieja pregunta, pero si usted recuerda. ¿Por qué no usaste matrices de bytes en parámetros de constructor en lugar de secuencias? – Oscar