C#中泛型类的专业化模式?

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)

它可以让你有点脑弯曲,但它可以工作.


Mar*_*ade 9

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)