Ich versuche, Operatorüberladungen durchzuführen +=
, kann dies aber nicht. Ich kann nur einen Bediener überladen +
.
Woher?
Bearbeiten
Der Grund, warum dies nicht funktioniert, ist, dass ich eine Vektorklasse habe (mit einem X- und Y-Feld). Betrachten Sie das folgende Beispiel.
vector1 += vector2;
Wenn meine Bedienerüberlastung auf Folgendes eingestellt ist:
public static Vector operator +(Vector left, Vector right)
{
return new Vector(right.x + left.x, right.y + left.y);
}
Dann wird das Ergebnis nicht zu Vektor1 hinzugefügt, sondern Vektor1 wird auch als Referenz zu einem brandneuen Vektor.
Antworten:
Überladbare Operatoren von MSDN:
Darüber hinaus kann keiner der Zuweisungsoperatoren überladen werden. Ich denke, das liegt daran, dass sich dies auf die Garbage Collection und die Speicherverwaltung auswirken wird, was eine potenzielle Sicherheitslücke in der stark typisierten CLR-Welt darstellt.
Mal sehen, was genau ein Operator ist. Laut dem berühmten Buch von Jeffrey Richter hat jede Programmiersprache eine eigene Operatorliste, die in speziellen Methodenaufrufen zusammengestellt wird, und CLR selbst weiß nichts über Operatoren. Mal sehen, was genau hinter den Operatoren
+
und bleibt+=
.Siehe diesen einfachen Code:
Sehen Sie sich den IL-Code für diese Anleitung an:
Nun sehen wir diesen Code:
Und IL-Code dafür:
Sie sind gleich! Der
+=
Operator ist also nur syntaktischer Zucker für Ihr Programm in C # , und Sie können den+
Operator einfach überladen .Beispielsweise:
Dieser Code wird kompiliert und erfolgreich ausgeführt als:
Aktualisieren:
Laut Ihrem Update - wie der @EricLippert sagt, sollten Sie die Vektoren wirklich als unveränderliches Objekt haben. Das Ergebnis der Addition der beiden Vektoren ist ein neuer Vektor, nicht der erste mit unterschiedlichen Größen.
Wenn Sie aus irgendeinem Grund den ersten Vektor ändern müssen, können Sie diese Überladung verwenden (aber für mich ist dies ein sehr seltsames Verhalten):
quelle
v3 = v1 + v2;
in Folgev1
sowie geändert wirdv3
ist ungewöhnlichIch denke, Sie finden diesen Link informativ: Überladbare Operatoren
quelle
Dies liegt daran, dass der Zuweisungsoperator nicht überladen werden kann. Sie können keinen Code schreiben, der die Zuweisung korrekt ausführen würde.
Von MSDN .
quelle
Sie können nicht überladen,
+=
da es sich nicht wirklich um einen eindeutigen Operator handelt, sondern nur um syntaktischen Zucker .x += y
ist nur eine Kurzschriftx = x + y
. Da+=
im Hinblick auf die definiert ist+
und=
Betreiber, so dass Sie es separat außer Kraft setzen könnte zu Problemen führen, in Fällen , in denenx += y
undx = x + y
nicht in der exakt gleichen Art und Weise verhalten.Auf einer niedrigeren Ebene ist es sehr wahrscheinlich, dass der C # -Compiler beide Ausdrücke bis auf denselben Bytecode kompiliert, was bedeutet, dass es sehr wahrscheinlich ist, dass die Laufzeit sie während der Programmausführung nicht unterschiedlich behandeln kann.
Ich kann verstehen, dass Sie es möglicherweise wie eine separate Operation behandeln möchten: In einer Anweisung wie
x += 10
Sie wissen Sie, dass Sie dasx
Objekt an Ort und Stelle mutieren und möglicherweise Zeit / Speicher sparen können, anstatt ein neues Objekt zu erstellen,x + 10
bevor Sie es der alten Referenz zuweisen .Beachten Sie jedoch diesen Code:
Sollte
a == b
am Ende? Für die meisten Typen ist neina
10 mehr alsb
. Aber wenn Sie den+=
Operator überlasten könnten , um an Ort und Stelle zu mutieren, dann ja. Betrachten Sie nun dasa
undb
um in weit entfernte Teile des Programms weitergegeben werden könnten. Ihre mögliche Optimierung kann zu verwirrenden Fehlern führen, wenn sich Ihr Objekt dort ändert, wo der Code dies nicht erwartet.Mit anderen Worten, wenn die Leistung so wichtig ist, ist es nicht allzu schwer, sie durch
x += 10
einen Methodenaufruf wie zu ersetzenx.increaseBy(10)
, und es ist für alle Beteiligten viel klarer.quelle
it's just syntactic sugar
zuit's just syntactic sugar in C#
; Andernfalls klingt es zu allgemein, aber in einigen Programmiersprachen ist es nicht nur syntaktischer Zucker, sondern kann tatsächlich Leistungsvorteile bringen.+=
könnte wahrscheinlich ein intelligenter Compiler optimiert werden, da die Arithmetik einfach ist. Sobald Sie sich jedoch mit Objekten befasst haben, sind alle Wetten ungültig. Jede Sprache hat so ziemlich die gleichen Probleme. Aus diesem Grund ist eine Überlastung des Bedieners böse.Dies liegt daran, dass dieser Operator nicht überladen werden kann:
MSDN
Nur Überlastungsoperator
+
, wegenx += y
gleichx = x + y
quelle
Operatorüberlastung für
+
wird im+=
Operator verwendet,A += B
gleichA = operator+(A, B)
.quelle
Wenn Sie den
+
Operator wie folgt überladen :du kannst tun
oder
Dies wird gleichermaßen kompiliert und ausgeführt.
quelle
Auf dieses Problem gibt es immer die gleiche Antwort: Warum brauchen Sie das
+=
, wenn Sie es kostenlos bekommen, wenn Sie das überladen+
. Aber was passiert, wenn ich so eine Klasse habe?Sagen Sie immer noch, dass es gut ist, dass das
+=
"automatisch implementiert" ist. Wenn Sie versuchen, Hochleistungsrechnen in C # durchzuführen, benötigen Sie solche Funktionen, um die Verarbeitungszeit und den Speicherverbrauch zu reduzieren. Wenn jemand eine gute Lösung hat, wird dies sehr geschätzt, aber sagen Sie mir nicht, dass ich dies mit statischen Methoden tun muss Dies ist nur eine Problemumgehung, und ich sehe keinen Grund, warum C # die+=
Implementierung ausführt, wenn sie nicht definiert ist und wenn sie definiert ist, wird sie verwendet. Einige Leute sagen, dass es keinen Unterschied gibt+
und+=
Fehler verhindert, aber ist das nicht mein eigenes Problem?quelle
+=
es Ihr eigenes Problem ist , die Semantik von durcheinander zu bringen ... das gilt nur, wenn niemand sonst jemals Ihren Code lesen, warten oder ausführen muss.List<T>
einem Operator wielist += "new item"
z. B. kein neues Element hinzufügen . Sie rufenAdd
stattdessen die Methode auf.Ich hatte genau die gleiche Frage und kann sie unmöglich besser beantworten als diese Person
quelle
Eine bessere Entwurfsmethode ist Explicit Casting. Sie können Casting definitiv überladen.
quelle