¿Considera aceptable o mala práctica crear una clase genérica abstracta que tome como parámetro de tipo una clase que se deriva de sí misma?Clases genéricas abstractas que toman parámetros de tipo derivados de esa clase
Esto permite que la clase genérica abstracta manipule instancias de la clase derivada y en particular la capacidad de crear nuevas() instancias de la clase derivada según sea necesario y puede evitar repetir código en las clases concretas que se derivan de ella.
Si es "malo", ¿qué alternativa prefiere manejar tales situaciones y cómo estructuraría el código a continuación?
Por ejemplo: -
// We pass both the wrapped class and the wrapping class as type parameters
// to the generic class allowing it to create instances of either as necessary.
public abstract class CoolClass<T, U>
where U : CoolClass<T, U>, new()
{
public T Value { get; private set; }
protected CoolClass() { }
public CoolClass(T value) { Value = value; }
public static implicit operator CoolClass<T, U>(T val)
{
// since we know the derived type and that its new(), we can
// new up an instance of it (which we couldn't do as an abstract class)
return new U() { Value = val};
}
public static implicit operator T(CoolClass<T, U> obj)
{
return obj.Value;
}
}
Y una segunda pregunta extra: ¿Por qué uno de estos operadores implícita trabajo y el otro no uno?
p. Ej.
public class CoolInt : CoolClass<int, CoolInt>
{
public CoolInt() { }
public CoolInt(int val) (val) { }
}
// Why does this not work
CoolInt x = 5;
// when this works
CoolInt x2 = (CoolInt)5;
// and this works
int j = x;
¿Qué pasa con la pregunta sobre los parámetros de tipo genérico? (Debería haber puesto la pregunta implícita en una pregunta separada ya que es una especie de distracción para la pregunta principal.) –
He actualizado la respuesta. –
+1 pero tengo que estar en desacuerdo con la desaprobación de las versiones implícitas.No hay código que no pueda descubrirse sin un análisis estático o un uso riguroso del depurador; y como desarrollador espero tener que hacer esto para analizar código más complejo. El complejo no es malo. En este caso, está haciendo que el consumidor de la clase sea más capaz de hacer lo que quiera. –