通用方法:返回 double 或 double-like class

Generic methods: returning double or double-like class

我目前正在使用 C# 中的运算符重载实现算法微分的简单版本。我正在尝试弄清楚如何设计适用于普通双精度和我自己的 class "ADouble" 的通用数学函数,它像双精度一样工作,但会重载 +、*、- 等算术运算符第四。

例如,我想创建一个像

这样的函数
Public T MathFunction<T>(T x) where T : "is either double or Adouble"
{
    if (x > 0)
         return new T(1.0)
    else
        // something
}

对双打和双打都适用。在这种情况下,我有必要 "new up" 一个特定的值(这里是 1.0)。在其他情况下,我可能不得不做类似

的事情
Public T MathFunction<T>(T x) where T : "is either double or Adouble"
{
     T temporaryVar = 2*x;
     // .. More calculations
     return "some T";
}

我已经实现了必要的接口来像上面那样进行比较,但我无法让其余的工作。

我可以用双倍实例化我的 ADouble class,比如

Adouble myADouble = new ADouble(12.3);

但是显然,double 没有这样工作的构造函数。我尝试过不同的东西。首先我想到了

if (typeof(T) == typeof(ADouble)
    return new ADouble(1.0)

但这不起作用,因为该函数无法将 ADouble 显式转换为 T(我理解)。

有人建议我如何实现适用于我的 ADouble class 和双打的通用计算函数吗?还是制作具有不同签名的多种方法的唯一选择?也非常感谢对设计的不同建议。

Or is the only option to make multiple methods with different signatures?

称为"method overloading"。

是的。这是表达 "type A or type B" 约束的正确方法,特别是因为即使您可以成功地将其表达为通用约束,您仍然面临着调用适当的构造函数的挑战。

C# 泛型中没有机制可以使语句 return new T(1.0); 成功编译。这样做需要一些语法,将类型额外限制为具有 double 类型的单个参数的构造函数,而 C# 中没有此类功能。

this does not work, since the function cannot cast ADouble to a T explicitly

其实就是不能隐式施放。但是,足够接近了。 :)

这将是您必须清除的下一个障碍。具有讽刺意味的是,这是最简单的。那里的问题是,当您编写表达式时,编译器足够了解正在发生的事情,知道它不能保证转换成功。但是,如果您先将值转换为 object,则可以在编译器不报错的情况下将其转换为 T

请注意,我并不是建议您这样做。这里真正的问题是您正在尝试将通用语法用于真正不通用的东西。通用代码适用于可以使用 any 类型或至少是广义约束类型的地方。如果您有特定 类型,尤其是如果每个特定类型的实现不同,那么您不应该使用泛型。

在那种情况下,方法重载更为合适。


旁白:假设您的 ADouble 类型在字面上等同于 double,并且您可以在不丢失任何数据的情况下实现转换,您应该考虑编写隐式转换,以帮助创建类型可互换。看起来像这样:

public static implicit operator ADouble(double value)
{
    return new ADouble(value);
}

然后你可以用简单的赋值初始化ADouble值,比如:

ADouble adouble = 1.0;