문제
오버로드 된 연산자에게 새 개체를 반환하는 것만으로도 유일한 일이 있습니다. 오른쪽?
- 큰 버퍼가 포함 된 클래스 (x)가있는 경우
- 버퍼의 일부에는 내용이 포함되어 있으며 REST는 무료입니다.
- 두 피연산자의 추가 된 내용이 포함 된 새 개체를 만들어 두 개의 객체 (동일한 유형)를 병합하기 위해 Binary + 연산자에 과부하를 걸었습니다.
다시 말해:
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
이것은 x의 자유 부분에서 y의 내용을 복사하는 것이 훨씬 빠를 수 있기 때문에 고통 스럽습니다. 그렇게하면 우리는 큰 물체를 복사하지 않고 멋진 쓰레기 수집가에게 엉망진창을 남깁니다.
나는 이것이 간단한 x.add (y)로 수행 될 수 있음을 알고 있습니다. 연산자를 사용하여 수행 할 수있는 방법이 있는지 궁금합니다. 예를 들어, 우리는 할당 연산자 안에 있고 최적화 된 루틴을 수행하는 것을 알아냅니다.
해결책
나는 개인적으로 C#이 이것을 구현 한 방법을 좋아합니다.
더 "명백한"것입니다.
x += y;
그리고
x = x + y;
동일한 행동이 있어야합니다. C#에서는 이것이 시행됩니다. 별도의 과부하로 사람들은 운영자를 남용하고이를 동일하게 행동하지 못하게 할 수 있습니다.
perf 차이는 너무 최소화되어 구현 및 유지 관리가 더 쉽기 때문에 C# 접근 방식을 강력하게 선호합니다.
다른 팁
모든 수학적 이진 연산자는 새 개체를 반환합니다. 예를 들어, 당신은 2+3이 당신이 그들을 추가했기 때문에 그들 중 하나의 값을 5로 바꾸는 것을 원하지 않을 것입니다. 다시 말해, 해당 연산자의 의미론은 매우 명확하고 사양을 통해 시행됩니다. 다른 것을 원한다면 다른 것을 만들어야합니다 :). 그리고 나는 C ++와 비교하여 A = B = C를 과부하로 만들 수있는 C ++와 비교하여 C가 삭제되고 B가 할당되지 않았으며 C 또는 B와 관련하여 값이 동일합니다.