假设我有一个Vector3
带有重载运算符 * 的类型,允许乘以双精度数:
public readonly struct Vector3
{
public double X { get; }
public double Y { get; }
public double Z { get; }
public Vector3f(double x, double y, double z)
{
X = x;
Y = y;
Z = z;
}
public static Vector3f operator *(in Vector3f v, in double d) => new Vector3f(d * v.X, d * v.Y, d * v.Z);
}
只有一个重载,类似于表达式new Vector3(1,2,3) * 1.5
将编译但1.5 * new Vector3(1,2,3)
不会。由于向量标量乘法是可交换的,我希望任一顺序都可以工作,因此我添加了另一个重载,其参数反转,只会调用原始重载:
public static Vector3f operator *(in double d, in Vector3f v) => v * d;
这是做事的正确方法吗?是否应该将第二个重载实现为
public static Vector3f operator *(in double d, in Vector3f v) => new Vector3f(d * v.X, d * v.Y, d * v.Z);
反而?天真地,我希望编译器优化“额外”调用,并尽可能使用第一个重载(或者可能用长重载的主体替换短重载的主体),但我不知道的行为C# 编译器足以说明任何一种方式。
我意识到,在许多情况下,这是一种与算法选择相形见绌的性能问题,但在某些情况下,挤压每一次性能下降是至关重要的。在性能关键的情况下,是否应该将交换运算符重载实现为两个除了参数顺序之外都相同的重载,还是将一个委托给另一个委托是否同样有效?