Я пытаюсь выполнить перегрузку оператора +=
, но не могу. Могу сделать только перегрузку оператора для +
.
Как придешь?
редактировать
Причина, по которой это не работает, заключается в том, что у меня есть класс Vector (с полями X и Y). Рассмотрим следующий пример.
vector1 += vector2;
Если моя перегрузка оператора установлена на:
public static Vector operator +(Vector left, Vector right)
{
return new Vector(right.x + left.x, right.y + left.y);
}
Тогда результат не будет добавлен в vector1, а вместо этого vector1 также станет новым вектором по ссылке.
Ответы:
Перегружаемые операторы из MSDN:
Более того, ни один из операторов присваивания не может быть перегружен. Я думаю, это потому, что это повлияет на сборку мусора и управление памятью, что является потенциальной дырой в безопасности в мире строгой типизации CLR.
Тем не менее, давайте разберемся, что такое оператор. Согласно знаменитой книге Джеффри Рихтера , у каждого языка программирования есть свой список операторов, которые составляются в вызовах специальных методов, а сама среда CLR ничего не знает об операторах. Итак , давайте посмотрим , что именно остается позади
+
и+=
операторов.Посмотрите этот простой код:
Давайте посмотрим на IL-код этой инструкции:
Теперь посмотрим на этот код:
И IL-код для этого:
Они равны! Таким образом,
+=
оператор - это просто синтаксический сахар для вашей программы на C # , и вы можете просто перегрузить+
оператор.Например:
Этот код будет скомпилирован и успешно запущен как:
Обновить:
Согласно вашему обновлению - как говорит @EricLippert, вы действительно должны иметь векторы как неизменяемый объект. Результатом сложения двух векторов является новый вектор, а не первый с разными размерами.
Если по какой-то причине вам нужно изменить первый вектор, вы можете использовать эту перегрузку (но как по мне, это очень странное поведение):
источник
v3 = v1 + v2;
результат вv1
изменяется, а такжеv3
необычнаДумаю, вы найдете эту ссылку информативной: Перегружаемые операторы
источник
Это происходит по той же причине, что оператор присваивания не может быть перегружен. Вы не можете написать код, который правильно выполнял бы назначение.
Из MSDN .
источник
Вы не можете перегрузить,
+=
потому что на самом деле это не уникальный оператор, это просто синтаксический сахар .x += y
это просто сокращенный способ написанияx = x + y
. Потому что+=
определяется в терминах+
и=
операторов, что позволяет переопределить его отдельно может создать проблемы, в тех случаях , когдаx += y
иx = x + y
не ведут себя точно так же.На более низком уровне весьма вероятно, что компилятор C # компилирует оба выражения до одного и того же байт-кода, а это означает, что весьма вероятно, что среда выполнения не сможет обрабатывать их по-разному во время выполнения программы.
Я понимаю, что вы можете рассматривать его как отдельную операцию: в таком заявлении, как
x += 10
вы знаете, что вы можете изменитьx
объект на месте и, возможно, сэкономить время / память, вместо того, чтобы создавать новый объектx + 10
перед назначением его по старой ссылке ,Но рассмотрим этот код:
Должен
a == b
в конце? Для большинства типов нет,a
на 10 большеb
. Но если бы вы могли перегрузить+=
оператор для изменения на месте, тогда да. Теперь рассмотрим , чтоa
иb
может получить розданы в отдаленные части программы. Ваша возможная оптимизация может создать сбивающие с толку ошибки, если ваш объект начнет меняться там, где этого не ожидает код.Другими словами, если производительность так важна, ее не так сложно заменить
x += 10
вызовом метода, напримерx.increaseBy(10)
, и это намного понятнее для всех, кто участвует.источник
it's just syntactic sugar
наit's just syntactic sugar in C#
; в противном случае это звучит слишком обобщенно, но в некоторых языках программирования это не просто синтаксический сахар, но может действительно дать повышение производительности.+=
Вероятно , можно было бы оптимизировать умный компилятор, потому что арифметика проста. Но когда вы имеете дело с объектами, все ставки отменены. Любой язык сталкивается с примерно одинаковыми проблемами. Вот почему перегрузка операторов - зло.Это потому, что этот оператор не может быть перегружен:
MSDN
Просто перегрузите
+
оператор из-заx += y
равноx = x + y
источник
Перегрузка оператора для
+
используется в+=
операторе,A += B
равноA = operator+(A, B)
.источник
Если вы перегрузите
+
оператор следующим образом:ты можешь сделать
или
Это будет компилироваться и работать одинаково.
источник
На эту проблему всегда есть один и тот же ответ: зачем вам это
+=
, если вы получаете его бесплатно, если вы перегружаете+
. Но что будет, если у меня будет такой класс.Вы все еще говорите, что это хорошо, что
+=
он «реализован автоматически». Если вы попытаетесь выполнить высокопроизводительные вычисления на C #, вам понадобятся такие функции, чтобы сократить время обработки и потребление памяти, если у кого-то есть хорошее решение, оно будет высоко оценено, но не говорите мне, что я должен делать это с помощью статических методов. , это всего лишь обходной путь, и я не вижу причин, по которым C # выполняет+=
реализацию, если она не определена, и если она определена, она будет использоваться. Некоторые говорят, что отсутствие разницы между ошибками+
и+=
предотвращение ошибок, но разве это не моя проблема?источник
+=
вашей собственной проблемой ... это верно только в том случае, если никому больше не нужно читать, поддерживать или выполнять ваш код.List<T>
помощью оператораlist += "new item"
. Вы называете этоAdd
Вместо этого метод.У меня был точно такой же вопрос, и я не могу ответить на него лучше, чем у этого человека
источник
Лучшим методом проектирования является явное приведение. Однозначно можно перегрузить Casting.
источник