В C # я иногда хотел бы создать специальные методы для определенных "экземпляров" универсальных классов.
ОБНОВЛЕНИЕ: следующий код - просто тупой пример более абстрактной проблемы - не зацикливайтесь на временных рядах, а просто на принципах «добавления дополнительных методов» для определенного T .
Пример:
class Timeseries<T>
{
...
TimeSeries<T> Slice(...) { ... }
}
В случае, когда T двойное, я хотел бы использовать несколько дополнительных методов, таких как Integrate()
, Interpolate()
и т. Д., Которые имеют смысл только для double
, потому что мне нужно выполнять арифметику для них.
Есть несколько способов сделать это, но я не могу найти тот, который меня устраивает.
1. Наследовать в особый класс
class TimeseriesDouble : Timeseries<double>
{
double Interpolate(...) { ... }
...
}
cons: TimeseriesDouble.Slice()
вернет новый объект Timeseries<double>
, теперь отсутствуют мои специальные методы.
2. Внешние методы
public static double Interpolate(Timeseries<double> ts, ...) { ... }
минусы: Разрывы с принципами ОО. И я не хочу откладывать свои методы. Кроме того, методы могут нуждаться в закрытом / защищенном состоянии.
3. Методы расширения
То же, что 2, только с более приятным синтаксисом вызова.
4. Общий базовый класс
class TimeSeries_base { ... }
class TimeSeries<T> : TimeSeries_base { .. typesafe versions of methods .. }
class TimeSeriesDouble : TimeSeries_base { .. typesafe versions of methods .. }
минусы: слишком много дублирования вещей из TimeSeries_base
в два подкласса. Базовый класс может стать просто заполнителем для служебных функций для подклассов.
pro: Теперь я могу делать такие вещи, как List<TimeSeries_base>
динамически.
5. Просто забудь про общий класс
Т.е., в коде держите Timeseries<T>
и TimeseriesDouble
отдельно.
минусы: Тогда я не получаю всех преимуществ от обработки TimeseriesDouble
как TimeSeries<T>
, например, объединение двух временных рядов с ZIP (A, B), где один из них имеет значение double.
Есть еще идеи?
В настоящее время я думаю, что мне больше всего нравится дизайн (1).