【发布时间】:2012-02-13 19:04:26
【问题描述】:
假设我有一个只有一个字段的结构:
public struct Angle
{
public static readonly double RadiansPerDegree = Math.PI / 180;
private readonly double _degrees;
public Angle(double degrees)
{
_degrees = degrees;
}
public double Degrees
{
get { return _degrees; }
}
public double Radians
{
get { return _degrees * RadiansPerDegree; }
}
public static Angle FromDegrees(double value)
{
return new Angle(value);
}
public static Angle FromRadians(double value)
{
return new Angle(value / RadiansPerDegree);
}
}
这很好用,直到我想做这样的事情:
var alpha = Angle.FromDegrees(90);
var beta = Angle.FromDegrees(100);
var inequality = alpha > beta;
var sum = alpha + beta;
var negation = -alpha;
//etc.
所以,我实现了IEquatable<in T> 和IComparable<in T>,但仍然没有启用任何运算符(甚至没有启用任何运算符(甚至==、<、>= 等)。
所以,我开始提供运算符重载。
例如:
public static Angle operator +(Angle a, Angle b)
{
return new Angle(a._degrees + b._degrees);
}
public static Angle operator -(Angle a)
{
return new Angle(-a._degrees);
}
public static bool operator >(Angle a, Angle b)
{
return a._degrees > b._degrees;
}
这很奏效,但是,当我查看所有可能超载的运算符 (+, -, !, ~, ++, --, true, false, +, -, *, /, %, &, |, ^, <<, >>, ==, !=, <, >, <=, >=) 时,我开始觉得一定有更好的方法。毕竟struct只包含一个字段,而那个字段是值类型。
有没有办法一次性启用double的所有运算符?还是我真的必须手动输入我可能想要支持的每个运算符?
(即使我有两个或三个字段,我仍然希望能够批量添加运算符...)
【问题讨论】:
-
您可能会添加隐式转换到(也可能来自)
double类型来做到这一点。不过,我脑海中的某些事情告诉我,这可能不是一个好主意,可能会导致模棱两可。 -
如果您真的只是为了度数和弧度转换而这样做,为什么不只使用一个实现这些功能的静态 MathHelper 类并使用 double 而不是创建一个重新发明另一个类的类不同的名字?
-
@Jeff Mercado,实际上,我认为隐式转换可能正是我正在寻找的。您会考虑将您的评论转换为答案吗?另外,如果真的有缺点,如果您能对此进行扩展,我将不胜感激。谢谢。
-
@DanM:这有点问题,我真的不知道这是否有不利之处,我有一种奇怪的感觉。这让我不愿意建议作为答案。
-
@Jeff,很公平,尽管让它成为一个答案会给社区一个更好的参与机会。看看msdn.microsoft.com/en-us/library/z5z9kes2.aspx,这个特定的例子似乎符合隐式的预期用法投掷。您应该能够在任何双精度和任何角度之间进行转换(例如,
Angle a = -720将被解释为 0 度或 0 弧度,没有必要例外)。如果结构是Distance而不是Angle,那么它就不会那么简单了。你能有负距离吗?
标签: c# .net struct operators operator-overloading