Перегрузка +/- унарные операторы - PullRequest
3 голосов
/ 23 апреля 2009

Когда вы перегружаете унарные операторы для неизменяемого типа, вы можете написать его так:

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 ]

7 голосов
/ 23 апреля 2009

В любом случае это хорошо. Вы не изменяете исходный объект ни в одном из двух методов.

Если вы вызываете string.substring(0, string.length()), нет причины, по которой исходная строка не может быть возвращена.

Единственный контракт, который вы заключаете с неизменяемостью, заключается в том, что после создания объекта он не изменяется.

3 голосов
/ 23 апреля 2009

На мой взгляд, это зависит от реализации 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

При семантике значений на самом деле не имеет значения, создаете ли вы новый объект или нет. Вы можете просто вернуть то же самое, чтобы избежать создания мусора.

Если у вашего типа есть ссылочная семантика, вы, вероятно, захотите, чтобы унарный плюс создал новый объект, чтобы он вел себя так же, как и другие операторы.

2 голосов
/ 23 апреля 2009

Я не могу представить себе случай, когда это имело бы значение для неизменяемого типа. Лучше всего просто вернуть p по принципу наименьшего удивления .

2 голосов
/ 23 апреля 2009

Если структура неизменна, вы можете выбрать, я бы вернул исходное значение.

Если изменяемый, вернуть новый.

1 голос
/ 23 апреля 2009

Гм ....

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.

1 голос
/ 23 апреля 2009

Я бы предпочел второй метод (хотя он был бы медленнее), но предполагая, что Point3 - это 3D-точка, вероятно, это struct, а не class.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...