C# оптимизирует перегруженные операторы

StackOverflow https://stackoverflow.com/questions/1804916

  •  05-07-2019
  •  | 
  •  

Вопрос

Кажется, единственным выходом является возврат нового объекта для перегруженных операторов.Верно?

  • Если у вас есть класс (X), содержащий большой буфер
  • Часть буфера содержит контент, остальное свободно.
  • Вы перегрузили двоичный оператор + для объединения двух объектов (одного типа), создав новый объект, содержащий добавленное содержимое обоих операндов.

Другими словами:

z = x + y // z is a new object containing the appended data from x and y. 

Это, очевидно, хорошо, потому что мы не хотим искажать x или y во время операции.Однако в спецификациях языка C# 7.2.2 говорится:

Когда бинарный оператор перегружен, соответствующий оператор присваивания (если есть) также неявно перегружается.

это значит, что:

x += y;  // will create a new x, copy contents of old x merged with y 
         //  and the old x will be garbage collected at some point

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

Я понимаю, что это можно сделать с помощью простого x.Add(y).Мне любопытно, есть ли способ сделать это с помощью операторов.например, чтобы выяснить, что мы находимся внутри оператора присваивания и выполнить оптимизированную процедуру.

Это было полезно?

Решение

Лично мне нравится, как это реализовано в C#.

Более «очевидно», что:

x += y;

и

x = x + y;

Должно иметь такое же поведение.В C# это реализовано.При раздельных перегрузках люди могут злоупотреблять оператором и препятствовать тому, чтобы он действовал одинаково.

Разница в производительности будет настолько минимальной, что также облегчит реализацию и поддержку, поэтому я настоятельно предпочитаю подход C#.

Другие советы

Все математические бинарные операторы возвращают новый объект.Например.Вы бы не хотели, чтобы 2+3 изменило значение одного из них на пять только потому, что вы их складывали.Другими словами, семантика рассматриваемых операторов очень ясна и закреплена в спецификациях.Если вы хотите чего-то другого, вам придется сделать что-то другое :).И мне лично это нравится по сравнению с C++, где вы можете сделать перегрузку, например, A=B=C может привести к удалению C, неназначению B и присвоению A любого значения, независимо от C или B.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top