通用方法:返回 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;
我目前正在使用 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;