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

时间:2008-11-11 22:11:51

标签: c# .net design-patterns generics

在C#中,我有时希望能为泛型类的某些“实例化”创建特殊方法。

更新:以下代码只是一个更抽象问题的愚蠢例子 - 不要过多关注时间序列,只是为某些T“添加额外方法”的原则。 / p>

示例:

class Timeseries<T> 
{ 
    ...
    TimeSeries<T> Slice(...) { ... }
}

在T为double的情况下,我想要一些额外的方法,例如Integrate()Interpolate()等等,只对double有意义,因为我需要做算术在他们身上。

有几种方法可以做到这一点,但我找不到一个我满意的方法。

1。继承为特殊类

class TimeseriesDouble : Timeseries<double>
{ 
    double Interpolate(...) { ... }
    ...
}

缺点: TimeseriesDouble.Slice()会返回一个新的Timeseries<double>对象,现在错过了我的特殊方法。

2。外部方法

public static double Interpolate(Timeseries<double> ts, ...) { ... }

缺点:违反OO原则。而且我不想放弃我的方法。此外,这些方法可能需要私有/受保护状态。

第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到两个子类的重复过多。基类可能只是子类的实用程序函数的占位符。

亲:我现在可以动态地执行List<TimeSeries_base>等操作。

5。忘掉一个共同的课程

即,在代码中保持Timeseries<T>TimeseriesDouble分开。

缺点:然后我无法像TimeseriesDouble一样处理TimeSeries<T>,例如将两个时间序列与ZIP(A,B)组合在一起,其中一个恰好是双打。


还有其他想法吗? 目前,我认为我最喜欢设计(1)。

4 个答案:

答案 0 :(得分:12)

你总是可以使用自引用泛型技巧:

public class TimeSeries<T, U> where U : TimeSeries<T, U>
{
    U Slice(...)
}

public class TimeSeriesDouble : TimeSeries<double, TimeSeriesDouble>
{
    ...
}

它可能有点弯曲,但它可以工作。

答案 1 :(得分: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() { ... }
 }

答案 2 :(得分:1)

我会选择(1)并在适当的时候施展。

 TimeSeriesDouble tsD = new TimeSeriesDouble();
 TimeSeriesDouble subTSD = tsD.Slice(...) as TimeSeriesDouble;

答案 3 :(得分:0)

我会考虑实现一个工厂来返回适当的子类。