Operatorüberladung und verschiedene Typen

8

Ich habe eine Klasse Score, die in Vergleichen mit Ganzzahlen stark verwendet wird. Ich plante, den Operator == zu überladen, um diese Vergleiche gemäß dem folgenden Code zu ermöglichen?

%Vor%

Ist dies eine sinnvolle Verwendung der Überladung des Operators?

Sollte ich Überlastungen für die linken und rechten Seiten der Bediener bereitstellen, damit die Nutzung symmetrisch ist?

    
Adrian Russell 14.08.2011, 03:51
quelle

5 Antworten

9

Ich könnte weitermachen und eine implizite Konvertierung von int nach Score definieren, so dass Sie nur mit einem einzigen Typ arbeiten müssen, wenn Sie mit Gleichheit umgehen.

%Vor%

Und während Sie Ihren eigenen == -Operator definieren, sollten Sie daran denken, != zu definieren und Equals und GetHashCode zu überschreiben.

    
Anthony Pegram 14.08.2011, 04:42
quelle
3

Normalerweise, wenn ich einen überladenen Operator sehe, vergleicht er diese Klasse mit sich selbst. Wenn Sie also mehrere Instanzvariablen haben, würden Sie herausfinden, wie Sie die beiden vergleichen können, um festzustellen, ob etwas gleich, größer, kleiner usw. war.

Ich verstehe nicht, warum Sie nicht nur tun:

%Vor%     
Justin 14.08.2011 03:59
quelle
2

"Ist das eine vernünftige Verwendung der Bedienerüberlastung?"

Wenn es Ihren Code leichter verständlich macht und keine Probleme verursacht, würde ich sagen, ja, absolut! Es kann auch andere Wege geben, aber wenn das für Sie funktioniert, sehe ich kein Problem.

"Sollte ich Überlastungen für die linken und rechten Seiten der Bediener bereitstellen, damit die Nutzung symmetrisch ist?"

Ich würde behaupten, dass Sie es nicht brauchen werden, wenn Sie nicht einen bestimmten Grund dafür haben, mit anderen Worten, wenn Sie sie brauchen oder brauchen. (YAGNI) Die einzige wirkliche Ausnahme, die ich sehe, ist, wenn Sie ein Framework schreiben, wo Sie eine ziemlich gute Idee haben, dass jemand anderes es brauchen wird.

    
shelleybutterfly 14.08.2011 03:56
quelle
2

Ich denke, das ist eine seltsame Situation, um eine Überlastung des Operators zu verwenden, aber es ist Ihr Anruf.

Mein Hauptpunkt ist jedoch, dass Sie, wenn Sie == überladen, auch überladen werden müssen! =

Wenn Sie dann überladen! =, der Teil, in dem Sie x vergleichen, um zu überprüfen, dass es nicht null ist, indem Sie x != null verwenden, ruft der Operator == den Operator! = auf. Dies ist an sich kein Problem, solange dies nicht einen == Vergleich verwendet, da Sie eine rekursive Menge von Aufrufen haben, die zu einem Stapelüberlauf führen.

Da aber viele Leute beim Überladen! = es als 'not ==' implementieren - wird dies in Ihrem Fall zu einem Stapelüberlauf führen.

Lösung: Insbesondere beim Überladen von ==,! = und Equals (), verwenden Sie am besten Object.ReferenceEquals(x, null); , wenn Sie mit null vergleichen.

    
iandotkelly 14.08.2011 04:13
quelle
0

tl; dr Im großen Plan der Dinge; Nein, das ist keine vernünftige Idee.

  1. Die Tatsache, dass man das Bedürfnis verspürt, nach dieser Frage zu fragen oder zu suchen, ist bereits aussagekräftig.
  2. Die Tatsache, dass sich nur wenige Menschen dafür interessieren, deutet darauf hin, dass es eine Möglichkeit geben könnte, einfach die Situation zu vermeiden, in der Sie die Frage zunächst stellen müssen.
  3. Diese beiden letzten Punkte sollten Sie zumindest dazu zwingen, einige Dinge zu überdenken, wie auch immer sie nicht scheinen mögen .

Sie sollten so schnell wie möglich und außerhalb Ihrer Domänenlogik Typen für alle Eingaben zu Ihrer Softwarekomponente zuweisen. Auf diese Art und Weise, was wir gemeinhin als "Domänenmodell" bezeichnen, muss man sich darüber keine Gedanken machen.

In Ihrem Fall bedeutet das, dass alle Scores in Score -Objekte eingeschlossen werden. Weil sie das sind. Die Notwendigkeit, Ausnahmen zu machen, ist immer mindestens zweifelhaft und qualifiziert sich als Code-Geruch.

Der nächste Schritt besteht darin, Ihr "Domänenmodell" als nichts Besonderes anzusehen - nur ein weiterer Satz von Modulen. Sehen Sie sich all diese (zu oft unangenehmen) I / O-Schnittstellen an, die handfeste Primitive verwenden, um eine eigene / separate Rolle zu erfüllen. Dies wird natürlich (und fast magisch) die individuelle Komplexität all Ihrer Komponenten (z.B. Klassen) reduzieren.

Ein Nebeneffekt davon ist, dass Sie vielleicht genau diese Frage für unsinnig finden. "Warum sollte ich jemals eine Partitur mit einer primitiven Ganzzahl vergleichen müssen, wenn ich nicht einmal sicher bin, dass Integer eine Partitur ist? Und wenn ich mir sicher bin, warum habe ich das vorher nicht gesagt (zB durch Boxen)? "

Wenn Sie noch weiter gehen, werden Sie vielleicht feststellen, dass viele Ihrer Algorithmen nicht einmal wissen müssen, wie ein Punktestand gehalten wird: Es ist wahrscheinlich, dass die Mehrheit von ihnen nur in der Lage sein muss, sie zu vergleichen, um festzustellen, ob sie gleich sind sehen, was höher ist. Ich sage nicht, dass die Flexibilität, zu ändern, wie Sie die Punktezahl halten, in der Zukunft nützlich sein wird, aber in der Regel wenn es keine Rolle spielen sollte müssen Sie nicht binden Code zu einer Implementierung, nur um süß zu sein. Vielleicht überraschend, das gilt auch für Primitive wie Ganzzahlen und sogar das Konzept einer Zahl (die Sie nicht in allen Fällen interessieren müssen, in denen Sie nur zwei Noten vergleichen müssen). Die SOLID Grundsätze bieten eine gute Anleitung, bis Sie Intuitionen für sich selbst entwickeln können.

Counter: Man kann immer das Argument der Leistung bringen, um gegen diese Denkrichtung zu argumentieren. Meiner Erfahrung nach wurde das JIT optimiert und inline, was auch immer der Performance im Weg steht (besonders bei trivialen Dingen wie Gleichheitsvergleiche) und wenn es nicht so ist, gibt es fast immer einen Weg, Performance-kritischen Code vernünftig zu abstrahieren. Zögern Sie nicht, Ihre Typen zu versiegeln, wenn der Versand ein Problem darstellt.

Nach dem Messen und Finden eines Engpasses in einem korrekten Design , der nicht durch ein alternatives, aber ebenso vernünftiges Design behoben werden kann, muss man ehrlich sein, dass sie ein treffen Sprachbeschränkung , in diesem Fall sollte man entweder in Betracht ziehen, diesen Code zu extrahieren und ihn in eine passendere Sprache zu schreiben oder mit der existierenden Sprache herumzuhacken, aber den Code aus der Hölle kommentieren.

Abschließend möchte ich erwähnen, dass ich genau das getan habe, was Sie in der Vergangenheit vorgeschlagen haben, und ich kann nur dankbar sein, dass der betreffende Code nie in Produktion ging. Tu es einmal und es scheint nicht schädlich zu sein, aber mach es überall und dieses unbehagliche Gefühl setzt sich in dir fest und erzeugt nur Frustration, bis du schließlich erkennst, warum es falsch ist (nach den obigen Überlegungen). Wenn Sie neugierig sind, tat ich dies für Typen, die Entitätsschlüssel repräsentierten, die fast immer ein einzelnes Grundelement umschlossen. Wieder schien es eine vernünftige Idee zu sein und es könnte dir immer noch so vorkommen, aber ich glaube fest, dass es nicht jetzt ist, obwohl ich vorher nichts davon gehört hätte. Vielleicht ist es eines dieser Dinge, mit denen du dich verbrennst, bevor es schließlich versinkt.

    
tne 19.06.2015 11:48
quelle

Tags und Links