En C# A veces me gustaría poder hacer métodos especiales para ciertas "instancias" de clases genéricas.¿Patrón para la especialización de la clase genérica en C#?
ACTUALIZACIÓN: El siguiente código es solo un tonto ejemplo de un problema más abstracto: no se centre demasiado en series de tiempo, solo en los principios de "agregar métodos adicionales" para ciertos T.
Ejemplo:
class Timeseries<T>
{
...
TimeSeries<T> Slice(...) { ... }
}
En el caso donde T es el doble, me gustaría algunos métodos adicionales, como Integrate()
, Interpolate()
y así sucesivamente que sólo tienen sentido para double
, porque necesito hacer operaciones aritméticas sobre ellas .
Existen varias formas de hacerlo, pero no puedo encontrar una con la que esté satisfecho.
1. Heredar en una clase especial
class TimeseriesDouble : Timeseries<double>
{
double Interpolate(...) { ... }
...
}
contras:TimeseriesDouble.Slice()
devolverá un nuevo objeto Timeseries<double>
, ahora falta mis métodos especiales.
2. Métodos externos
public static double Interpolate(Timeseries<double> ts, ...) { ... }
contras: Rompe con los principios OO. Y no quiero apartar mis métodos. Además, los métodos pueden necesitar estado privado/protegido.
3. Los métodos de extensión
Igual que 2, sólo con una sintaxis llamar más agradable.
4. clase base común
class TimeSeries_base { ... }
class TimeSeries<T> : TimeSeries_base { .. typesafe versions of methods .. }
class TimeSeriesDouble : TimeSeries_base { .. typesafe versions of methods .. }
contras: demasiada duplicación de cosas de TimeSeries_base
en las dos subclases. La clase base podría convertirse simplemente en un marcador de posición para las funciones de utilidad para las subclases.
pro: Ahora puedo hacer cosas como List<TimeSeries_base>
dinámicamente.
5. Olvídate de una clase común
es decir, mantener Timeseries<T>
y TimeseriesDouble
separada en el código.
contras: entonces no obtener todos los beneficios del tratamiento de una TimeseriesDouble
como un TimeSeries<T>
, por ejemplo, combinando dos timeseries con ZIP (A, B), donde uno resulta ser de dobles.
¿Alguna otra idea? Actualmente, creo que me gusta el diseño (1) mejor.
Puede ser útil dar ejemplos más concretos del código de cliente que tiene, así como lo que es un TimeSeries. Si no lo hace, obtendrá muchas respuestas fuera de tema porque no hay suficiente información para seguir y la gente hará suposiciones. –
por ejemplo, no entiendo por qué (2) no puede devolver TimeSeries, o si eso es válido, por qué no puedo tener T interpolar estático público (Timeseries ts, ...) {...}, ¿Puedo tener un TimeSeries ? –
Sí, tal vez los ejemplos deberían ser más concretos. Pero pienso en esto como solo un ejemplo de un problema de diseño más general. Entonces, ¿debería expresar el problema de manera más abstracta, para que TimeSeries no se desvíe de la esencia? –