Probleme mit überladenem operator ==



  • genau das selbe kann man auch mit der ID machen.
    Wie hier "Tom" wird die ID geprüft. Nicht ob die Instanzen gleich sind.

    Logische Gleichheit heisst nicht, die Datenelemente alle zu vergleichen, sondern die Elemente zu vergleichen, die einen logischen Zustand definieren. Eine ID gehört IMHO nicht dazu.

    Was ist, wenn du in der ArrayList nur ein Tom drin haben willst. und bist fleissig am eintüten.
    Dabei musst du dann stets prüfen, ob ein Element mit diesen Namen (ID) bereits in der Liste ist.
    Dann machst du doch die Klasse über den Namen eindeutig um diese Logik in die Klasse einzubringen und den Zugriff auf die Klasse zu vereinfachen.



  • das macht natürlich nur Sinn, wenn die Operatoren später nicht für andere Vergleiche gebraucht werden, bedeutet es muss inhaltlich Richtig bleiben.
    Seine Klasse heisst: 'CollisionMaterial'. Wenn er später andere Eigenschaften des Material über die Operatoren vergleichen möchte, macht ein es natürlich kein Sinn, die ID zur Prüfung auf Gleichheit zu nehmen. Dann gebe ich dir Recht und würd dann lieber beim Eintüten in die ArrayList die ID selbst vergleichen.
    Aber dass ist eine inhaltliche Entscheidung und kein Problem der allgemeinen Handhabung von Equals oder den Operatoren.



  • Wow, da habe ich aber eine Diskussion angestoßen! Ist ja klasse.

    Nun. Zunächst zu meinem eigentlichen Problem: Ich habe durch die Diskussion festgestelt, dass ich falsch lag in der ganzen Implementierungs-Idee. Ich kann nicht einfach ein neues Material erzeugen, wenn es eine Id nicht gibt. Es muss vorher in der Xml-Datei spezifiezert und parametrisiert sein. Es gibt nämlich in der Tat noch andere Eigetnschaften, die ich dann nicht festlegen könnte. Daher muss ich eine Exception schmeißen, ewnn es das Material nicht gibt.

    Die Id brauche ich allerdings, da ich sonst das passende Material nicht mehr aus der Liste bekomme (vielleicht sollte man über eine Map (falls das in C# so heisst) nachdenken). Ich erzeuge die Materials ja zunächst, packe sie in die Liste und im nächsten, späteren Schritt suche ich sie wieder raus, wenn ich die referenzierenden Objekte erzeuge.

    Habt Dank, dass ich so den logisch-inhaltlichen Fehler gefunden habe 🙂

    Aber ich will mich auch an der Diskussion beteiligen. Ich denke eigentlich, dass wir gar nicht aneinander vorbeireden. Eigentlich besteht doch kein Zweifel (nachdem ich nun weiß, wozu Equals() da ist), was Identität und Gleichheit ist und dass Equals eben auf Gleichheit prüft.

    Aber was ist der == Operator?? Auf Ebene von object prüft er (wie Equal()) die Referenzen -- was auch sonst -- und damit auf Identität. Bei String prüft er auf Gleichheit. Und was prüft er in der Theorie / Philosophie des Programmierens??



  • genau das selbe kann man auch mit der ID machen.
    Wie hier "Tom" wird die ID geprüft. Nicht ob die Instanzen gleich sind.

    Ja, aber wenn die ID eindeutig ist? Dann werden die Instanzen geprüft.

    Und (jetzt kommt der Punkt):
    Wenn zwei Objekte gleich sind, aber die ID nicht, werden sie von diesem Equals() als "logisch ungleich" bewertet. Und das ist falsch.

    Dabei musst du dann stets prüfen, ob ein Element mit diesen Namen (ID) bereits in der Liste ist.
    Dann machst du doch die Klasse über den Namen eindeutig um diese Logik in die Klasse einzubringen und den Zugriff auf die Klasse zu vereinfachen.

    Ja, natürlich musst du das prüfen. Kommt drauf an, was du für deine ArrayList willst: Ob kein Elemente doppelt drin sind, oder ob überhaupt keine logisch gleichen Elemente mehrmals drin sind. Das zweite ist natürlich aufwändig, aber es geht halt nicht anders. Deshalb sollte man mit Equals() auch immer die Methode um einen Hashcode zu getten (weiss grad nicht wie die heisst), redefinieren. Da kann man dann gut von profitieren, weil nicht jedesmal Equals() aufgerufen werden muss.

    Aber dass ist eine inhaltliche Entscheidung und kein Problem der allgemeinen Handhabung von Equals oder den Operatoren.

    Das sehe ich anders. Was er mit dem operator== macht, ist ja eigentlich egal (ich würde ihn nur bei so mathematischen Sachen wie Brüche auf Gleichheit prüfen lassen). Aber Equals soll nicht die Identität vergleichen, aber das wird hier mit der ID gemacht (Ich gehe jetzt immer noch davon aus, dass IDs eindeutig sind).
    Was ich sowieso überhaupt schwachsinnig finde, weil da vergleiche ich gleich lieber die Referenzen.

    Ich weiss ehrlich gesagt nicht, warum du das wegdiskutieren willst. Es ist doch offensichtlich, dass hier, anstatt die Inhalte von so einem Material zu vergleichen die Identität (ID == Identität, das sagt ja der Name schon :p ) verglichen wird. Das ist doch Fakt. Dazu brauche ich mir doch nur den Sourcecode anschauen.



  • Aber was ist der == Operator?? Auf Ebene von object prüft er (wie Equal()) die Referenzen -- was auch sonst -- und damit auf Identität.

    Nein, Equals soll nicht die Referenzen vergleichen. Das macht natürlich das Equals von Object, was willst du denn für Object auch ein anderes Equals definieren? Aber es ist so gedacht, dass es nicht die Referenz, sondern den Inhalt vergleicht.

    Bei String prüft er auf Gleichheit. Und was prüft er in der Theorie / Philosophie des Programmierens??

    Was du für richtig hältst. Ich halte meistens die Identität für richtig, weil ich mir vorstelle, mit Zeigern zu arbeiten und damit die Zeiger vergleiche.
    Ne Ausnahme würde ich bei einer Klasse für Brüche oder Komplexe Zahlen machen. Und natürlich bei String, weil die Identität eines Strings eigentlich gar nichts nützt.



  • Wenn zwei Objekte gleich sind, aber die ID nicht

    Wie soll das denn gehen? Wann sind denn jetzt die Objekte gleich? Bei gleicher Referenz haben sie doch auch die gleiche Id. Und dann KANN sie ja gar nciht unterschiedlich sein. Wenn es zwei unterschiedliche Objekte sind (also andere Referenzen) und die Id unterschiedlich, dann sind es die beiden Objekte auch und man bekommt false zurück

    Kommt drauf an, was du für deine ArrayList willst: Ob kein Elemente doppelt drin sind, oder ob überhaupt keine logisch gleichen Elemente mehrmals drin sind. Das zweite ist natürlich aufwändig, aber es geht halt nicht anders.

    Das ist es, was ich will. Keine logisch gleichen Elemente (wsa sich primär an der Id festmacht).

    Deshalb sollte man mit Equals() auch immer die Methode um einen Hashcode zu getten (weiss grad nicht wie die heisst), redefinieren.

    Habe ich gemacht. Heißt übrigens treffender Weise GetHashCode() 😉 Aber so sagst Du ja plötzlich wieder, dass man Equals überschreiben soll, um die Id zu vergeleichen.

    Was ich sowieso überhaupt schwachsinnig finde, weil da vergleiche ich gleich lieber die Referenzen.

    Wie gesagt, kommen die Daten aus einem Xml-File. Da kann ich ja schlecht Referenzen reinschreiben. Daher brauche ich eine eindeutige Variable, die ich prima als Attribut / Childnode angeben kann. Als Klartext. Dieser wird dann geparst. Wenn ich die Materials erzeugt habe, anschließend wer weiß was mache und dann plötzlich aus dem Xml-File auf ein solches Material verweise, brauche ich die Id. Sonst geht es nicht.

    Aber was ist der == Operator?? Auf Ebene von object prüft er (wie Equal()) die Referenzen -- was auch sonst -- und damit auf Identität.
    Nein, Equals soll nicht die Referenzen vergleichen. Das macht natürlich

    Sorry, so habe ich es nicht gemeint. Mir ist klar, dass Equals die inhaltliche Gleichheit prüfen soll. Ich meinte, dass object keine andere Wahl hat, als die Referenzen zu nehmen. Statt "wie Equal()" müsste es heißen "wie im Falle von object auch Equal()", ok?

    Aber ich bin zu dre Überzeugung gekommen, dass ich die Methoden / Operatoren NICHT überschreibe. Ich teste, ob sich ein Material mit der gleichen Id in der Liste befindet. Wenn ja => return Referenz, else return null, was zu einer Exeption führt, da das Xml-File falsch war.



  • Wie soll das denn gehen? Wann sind denn jetzt die Objekte gleich? Bei gleicher Referenz haben sie doch auch die gleiche Id. Und dann KANN sie ja gar nciht unterschiedlich sein. Wenn es zwei unterschiedliche Objekte sind (also andere Referenzen) und die Id unterschiedlich, dann sind es die beiden Objekte auch und man bekommt false zurück

    Ich kann auch zwei Baugleiche Autos mit unterschiedlicher Seriennummer (ID) haben. Wenn du den Unterschied zwischen Gleichheit und Identität nicht verstehst, hat das keinen Sinn.
    Eine unterschiedliche ID ist doch keine Garantie dafür, dass zwei Objekte nicht gleichwertig sind.

    Das ist es, was ich will. Keine logisch gleichen Elemente (wsa sich primär an der Id festmacht).

    Ne, macht es sich nicht. Du kannst zwei gleiche Materialien haben, jeweils mit unterschiedlicher ID. Du verstehst den Begriff "logische Gleichheit" nicht richtig.

    Habe ich gemacht. Heißt übrigens treffender Weise GetHashCode() Aber so sagst Du ja plötzlich wieder, dass man Equals überschreiben soll, um die Id zu vergeleichen.

    Nein, das war an Andreas gerichtet und ich habe damit gesagt, dass man Equals verwenden soll um logische Gleichheit festzustellen und nicht die IDs/Referenzen zu vergleichen. GetHashcode() kann das beschleunigen, weil Objekte mit unterschiedlichem Hashcode nicht mehr mit Equals verglichen werden müssen.

    Es ist ja ok, wenn du nur die IDs vergleichen willst, aber dann benutze nicht Equals dafür, sondern z.B. RefEquals.
    Aber mach einfach, wie du für richtig hältst, ich denke, es ist alles gesagt.



  • Hi,

    ich will mich ja wirklich nicht streiten. Ich fand es eigentlich ne gute Diskussion. Ich habe leider die Id auf meinen Fall bezogen. Ich gebe Dir absolut Recht, dass beim Auto zwei IDs verschieden sein können, aber sie ansonsten baugleich sind. Sorry, ich war wirklcih auf meine CollisionMaterials fixiert. Und dort ist es wirklcih eine eineindeutige Erkennung.

    Und, wie gesagt, ich habe den Code wieder rausgeschmissen und vergleiche nicht mit Equal und auch nicht mit ==, sondern einfach mat1.Id == mat2.Id. Einverstanden?? 🙄



  • Hi,

    ich wollte nochmal auf folgenden Thread ("überladen von Vergleichs Operatoren") im Csharp Forum hinweisen. Die Antwort von VizOne ist sehr ausführlich und weist auf nette Methoden von object hin, wie ReferenceEquals()



  • Auf die hab ich auch hingewiesen. 😉


Anmelden zum Antworten