通用线性插值器:如何应对DateTime?

时间:2010-03-02 21:39:21

标签: c# generics

我想写一个LinearInterpolator类,其中X是X轴值的类型,Y是Y轴值的类型。我无法看到如何做到这一点,以便X可以是DateTime或double。该类如下所示(未经测试):

class LinearInterpolator<X, Y>
{
    private List<X> m_xAxis;
    private List<Y> m_yAxis;

    public LinearInterpolator(List<X> x, List<Y> y)
    {
        m_xAxis = x;
        m_yAxis = y;
    }

    public Y interpolate(X x)
    {
        int i = m_xAxis.BinarySearch(x);
        if (i >= 0)
        {
            return m_yAxis[i];
        }
        else
        {
            // Must interpolate.
            int rightIdx = ~i;
            if (rightIdx >= m_xAxis.Count)
                --rightIdx;
            int leftIdx = rightIdx - 1;

            X xRight = m_xAxis[rightIdx];
            X xLeft = m_xAxis[leftIdx];
            Y yRight = m_yAxis[rightIdx];
            Y yLeft = m_yAxis[leftIdx];

            // This is the expression I'd like to write generically.
            // I'd also like X to be compilable as a DateTime.
            Y y = yLeft + ((x - xLeft) / (xRight - xLeft)) * (yRight - yLeft);
            return y;
        }
    }
}

}

在C ++中很容易,但我是C#泛型的新手,所以任何帮助都会受到赞赏。

4 个答案:

答案 0 :(得分:1)

使用DateTime.Ticks作为插值。您可以使用long类型作为通用符号在不同时间间隔进行插值。

答案 1 :(得分:1)

要知道的一点是C#不支持操作符覆盖。 所以这样的代码不起作用。

spoulson说的一个解决方案是不使用泛型,并使用int或long而不是T,并使用DateTime.Ticks。

答案 2 :(得分:1)

从C#泛型做数学没有好办法,所以你必须做这样的事情:

Y y = FromDouble<Y>(ToDouble(yLeft) + ((ToDouble(x) - ToDouble(xLeft)) /
          (ToDouble(xRight) - ToDouble(xLeft))) *
          (ToDouble(yRight) - ToDouble(yLeft)));

double ToDouble(object val)
{
    if (val is DateTime)
        return (double)((DateTime)val).Ticks;
    else
        return Convert.ToDouble(val);
}

T FromDouble<T>(double val)
{
    if (typeof(T) == typeof(DateTime))
        return (T)Convert.ChangeType(new DateTime((long)val), typeof(T));
    else
        return (T)Convert.ChangeType(val, typeof(T));
}

我没有测试过代码,所以请考虑伪代码。

答案 3 :(得分:0)

感谢您的建议。我正在改变我的方法并编写一个仅适用于双打的内插器;我希望插值很快,所以不要在运行时进行类型检查。