Bja*_*ert 10 .net c# generics design-patterns
在C#中,我有时希望能为泛型类的某些"实例化"创建特殊方法.
更新:下面的代码只是一个更抽象问题的一个愚蠢的例子 - 不要太关注时间序列,只是为某些T"添加额外的方法"的原则.
例:
class Timeseries<T>
{
...
TimeSeries<T> Slice(...) { ... }
}
Run Code Online (Sandbox Code Playgroud)
在T是double的情况下,我想要一些额外的方法,比如Integrate(),Interpolate()等等只有意义double,因为我需要对它们进行算术运算.
有几种方法可以做到这一点,但我找不到一个我满意的方法.
1.继承一个特殊的类
class TimeseriesDouble : Timeseries<double>
{
double Interpolate(...) { ... }
...
}
Run Code Online (Sandbox Code Playgroud)
缺点: TimeseriesDouble.Slice()将返回一个新Timeseries<double>对象,现在缺少我的特殊方法.
2.外部方法
public static double Interpolate(Timeseries<double> ts, ...) { ... }
Run Code Online (Sandbox Code Playgroud)
缺点:打破OO原则.而且我不想放弃我的方法.此外,这些方法可能需要私有/受保护状态.
3.扩展方法
与2相同,只是使用更好的调用语法.
4.共同基类
class TimeSeries_base { ... }
class TimeSeries<T> : TimeSeries_base { .. typesafe versions of methods .. }
class TimeSeriesDouble : TimeSeries_base { .. typesafe versions of methods .. }
Run Code Online (Sandbox Code Playgroud)
缺点:太多的东西重复TimeSeries_base进入两个子类.基类可能只是子类的实用程序函数的占位符.
亲:我现在可以做List<TimeSeries_base>动态的事情了.
忘了一个普通的课
即,保持Timeseries<T>并TimeseriesDouble分开代码.
缺点:然后我没有得到TimeseriesDouble像处理一样的所有好处TimeSeries<T>,例如将两个时间序列与ZIP(A,B)组合,其中一个恰好是双打.
还有其他想法吗? 目前,我认为我最喜欢的设计(1).
Jon*_*eet 12
你总是可以使用自引用泛型技巧:
public class TimeSeries<T, U> where U : TimeSeries<T, U>
{
U Slice(...)
}
public class TimeSeriesDouble : TimeSeries<double, TimeSeriesDouble>
{
...
}
Run Code Online (Sandbox Code Playgroud)
它可以让你有点脑弯曲,但它可以工作.
interface ITimeSeries<T> { ... }
abstract class TimeSeriesBase<TS> where TS : TimeSeriesBase<TS>
{ public TS Slice() { ... }
}
class TimeSeries<T>:TimeSeriesBase<TimeSeries<T>>,ITimeSeries<T> {}
class TimeSeriesDouble:TimeSeriesBase<TimeSeriesDouble>,ITimeSeries<double>
{ public double Interpolate() { ... }
}
Run Code Online (Sandbox Code Playgroud)