3

当您重载 - 一元运算符时,对于不可变类型,您可以这样编写:

public static Point3 operator - (Point3 p)
{
    return new Point3 (-p.X, -p.Y, -p.Z);
}

但是对于+一元运算符,应该如何实现呢?像这样:

public static Point3 operator + (Point3 p)
{
    return p;
}

或像这样:

public static Point3 operator + (Point3 p)
{
    return new Point3 (p);
}
4

6 回答 6

7

无论哪种方式都很好。您没有在这两种方法中的任何一种中改变原始对象。

如果您调用string.substring(0, string.length()),则没有理由无法返回原始字符串。

您签署的唯一具有不变性的合同是,一旦创建了一个对象,它就不会改变。

于 2009-04-22T20:03:53.300 回答
3

在我看来,这取决于 Point3.Equals() 的实现。

考虑以下代码:

Dictionary<Point3, string> cache;
Point3 pointA = new Point3(1, 2, 3);
Point3 pointB = new Point3(1, 2, 3);
cached[pointA] = "Value Aaa";
cached[pointB] = "Value Bbb";
Console.WriteLine(cached[pointA]);
Console.WriteLine(cached[pointB]);

如果 Point3 具有引用语义(当它们是同一个对象时,pointA.Equals(pointB)),这将输出:

Value Aaa
Value Bbb

如果 Point3 具有值语义(当它们的 x、y 和 z 值相等时,pointA.Equals(pointB)),这将输出:

Value Bbb
Value Bbb

使用值语义,是否创建新对象并不重要。您可能只返回相同的内容以避免产生垃圾。

如果您的类型具有引用语义,您可能希望一元加号创建一个新对象,以便它的行为方式与其他运算符相同。

于 2009-04-22T20:40:29.017 回答
2

如果结构是不可变的,你可以选择,我会返回原始值。

如果可变,则返回一个新的。

于 2009-04-22T20:07:48.970 回答
2

我无法想象它会对不可变类型产生影响的情况。最好只是返回p原则上最不意外

于 2009-04-22T20:08:32.557 回答
1

我更喜欢第二种方法(虽然它会更慢),但假设Point3是一个 3D 点,它可能应该是 a structnot a class.

于 2009-04-22T20:02:30.327 回答
1

嗯……

public static Point3 operator - (Point3 p)
{
    return new Point3 (-p);
}

如果我错了,请纠正我,但这不会设置无限递归吗?您在一元 (-) 运算符方法中调用一元 (-) 运算符。

在我看来,你会想要这样做:

public static Point3 operator - (Point3 p)
{
    return new Point3 (-(p.X), -(p.Y), -(p.Z)); 
    // EDIT: Added parens for the sake of explicity. I don't recall the operator precedence in this case. 

}

假设您的 Point3 类上有这样的构造函数和属性。

于 2009-04-22T20:47:33.773 回答