重载+/-一元运算符

时间:2009-04-22 20:00:16

标签: c# .net operators

当你重载 - 一元运算符时,对于一个不可变类型,你可以像下面这样写:

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);
}

6 个答案:

答案 0 :(得分:7)

无论哪种方式都没问题。您没有在两种方法中改变原始对象。

如果您致电string.substring(0, string.length()),则无法返回原始字符串。

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

答案 1 :(得分: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具有值语义(pointA.Equals(pointB),当它们的x,y和z值相等时), 这将输出:

Value Bbb
Value Bbb

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

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

答案 2 :(得分:2)

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

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

答案 3 :(得分:2)

我无法想象它会对不可变类型产生影响的情况。最好只需principle of least surprise返回p

答案 4 :(得分:1)

我更喜欢第二种方法(虽然它会慢一些),但假设Point3是一个3D点,它应该是struct而不是class

答案 5 :(得分: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类上有这样的构造函数和属性。