string
-
loks schrieb:
q.e.d
Ja, ja, lustig. Aber wirklich konkret erklären kannst du mir die folgende Diskrepanz nicht, oder?
object o = new object(); string s; // Nicht jeder beliebige Datentyp kann implizit // in einen String umgewandelt werden: s = o; // Fehler! s = new string(o); // Fehler! // Selbst eine explizite Konvertierung würde // nicht funktionieren: s = (string)o; //Absturz! // Das einzige, was funktioniert: Ein simpler // Aufruf einer Funktion, die ganz normal einen // String zurückliefert: s = o.ToString(); // Andererseits: // Bei einer Stringverknüpfung ist ein expliziter // Aufruf nicht mehr nötig, weil der +-Operator, // im Gegensatz zum Konstruktor, Daten vom Typ // object annehmen kann: s = "Hallo, " + o;
Was bitteschön ist daran logisch? Die Umwandlung in einen String ist nicht mal ein eingebautes Sprachfeature. Sie funktioniert weder implizit noch explizit. Und string besitzt noch nicht einmal einen Konstruktor, der ein object entgegen nimmt. Und trotzdem wurde beim +-Operator die Ausnahme gemacht und für ihn als Parameter nicht nur string, sondern object festgelegt.
Kann mir jemand das erklären:
- Implizite Umwandlung von object in string --> Nicht möglich
- Explizite Umwandlung von object in string --> Stürzt bei nicht kompatiblen Typen ab./Wirft eine Exception.
- string-Konstruktor, der ein object entgegen nimmt --> Nicht vorhanden
- +-Operator bei string, der ein object entgegen nimmt --> Vorhanden!!!
-
WTF schrieb:
// Andererseits: // Bei einer Stringverknüpfung ist ein expliziter // Aufruf nicht mehr nötig, weil der +-Operator, // im Gegensatz zum Konstruktor, Daten vom Typ // object annehmen kann: s = "Hallo, " + o;
_oder_ weil automatisch o.ToString() aufgerufen wird...
-
Hallo
Logisch ist es aber wirklich nicht. Die Frage ist doch, ob du erwartest hast, dass tausende von Zeilen Code ohne solche Kleinigkeiten erstellt werden können. Du wirst so etwas immer finden. Sehr oft wahrscheinlich auch in deinen Code. Jetzt weißt du darum und kannst damit umgehen.
chrische
-
loks schrieb:
WTF schrieb:
// Andererseits: // Bei einer Stringverknüpfung ist ein expliziter // Aufruf nicht mehr nötig, weil der +-Operator, // im Gegensatz zum Konstruktor, Daten vom Typ // object annehmen kann: s = "Hallo, " + o;
_oder_ weil automatisch o.ToString() aufgerufen wird...
Ich glaube nicht, dass das irgendwas mit einem automatischen Aufruf zu tun hat. Ich kann's nicht genau belegen, aber ich gehe davon aus, dass es ganz simpel so ist, dass die Funktion des string-Operators so definiert ist, dass sie ein object entgegennimmt und in der Funktion wird dann natürlich ToString aufgerufen:
public static string operator +(string str, object obj)
Man hätte also statt dessen nur folgendes zu schreiben brauchen:
public static string operator +(string str, string newStr)
chrische5 schrieb:
Logisch ist es aber wirklich nicht. Die Frage ist doch, ob du erwartest hast, dass tausende von Zeilen Code ohne solche Kleinigkeiten erstellt werden können. Du wirst so etwas immer finden. Sehr oft wahrscheinlich auch in deinen Code. Jetzt weißt du darum und kannst damit umgehen.
Sicher wird es sowas auch in meinem Code geben. Aber mein Code ist nicht das .NET Framework. Und speziell dieses Ding hier ist ja nicht mal ein Implementierungsdetail in tausenden Zeilen Code, sondern eine Sache der öffentlichen Klassendefinition. Das ist nichts, was beim Coden entstanden ist, sondern hier hat der, der den string auf dem Papier entworfen hat, Mist gebaut.
-
Warum überschreibst du nicht einfach, von deinen Objekten
die toString()-Funktion, die du in meineDaten[i] hast?. Da die ja eh standardmäßig aufgerufen werden, wenn ein +- Operator im Spiel ist und einer der beiden Objekte kein String ist.
Ich verstehe auch nicht ganz deine Aufregung bei Ausgaben auf die Konsole ist das doch ein nettes Feature, da man einfach schreiben kann
System.Console.Out.Write("hallo" + 5);alternativ zum + Operator kannst du auch die concat Funktion nehmen
die ist mehrfach überladen wie der + Operator
-
Nahasapeemapetilon schrieb:
Warum überschreibst du nicht einfach, von deinen Objekten
die toString()-Funktion, die du in meineDaten hast?.Das war ja gerade das Problem: Ursprünglich war meine Variable ein String. Dann wurde es eine Klasse und die ToString-Funktion lieferte das Property ID zurück, welches identisch ist mit dem Inhalt, den die Variable hatte, als sie noch ein String war. Doch dann wurde ToString geändert, so dass sie jetzt "ID, Name" zurück gibt. Und da war dann der Bug. Hätte das Programm beim Ändern von string in eine selbst definierte Klasse sofort gemeckert, dass man nicht irgendein beliebiges Objekt an einen String anfügen kann, hätte ich alle Stellen im Programm gefunden und dort dann auf das ID-Property verwiesen.
Nahasapeemapetilon schrieb:
Ich verstehe auch nicht ganz deine Aufregung bei Ausgaben auf die Konsole ist das doch ein nettes Feature, da man einfach schreiben kann
System.Console.Out.Write("hallo" + 5);Ich hätte ja auch nichts dagegen gehabt, wenn der +-Operator noch Überladungen für die Grunddatentypen, Zahlen und char (bool wäre da schon wieder irgendwie unpassend), hätte. Aber das sollte es auch schon gewesen sein. object ist da definitiv unpassend. Oder wann wäre zu erwarten, dass ich ein Objekt vom Typ Thread oder Button an einen String anhänge, ohne dass die implizite Konvertierung ein Gedankenfehler ist? Nach dieser Logik wundere ich mich, dass man nicht auch jedes beliebige Objekt auf ein int addieren kann und er dann einfach GetHashCode nimmt.
Nahasapeemapetilon schrieb:
alternativ zum + Operator kannst du auch die concat Funktion nehmen
die ist mehrfach überladen wie der + OperatorDaraus folgt: Diese Funktion ist genauso schrottig. Ich hätte mir ja eben das Gegenteil gewünscht: Eine Funktion, die [i]nicht* mit object überladen ist, damit das Anhängen eines Datentyps, der normalerweise nicht durch einen geschriebenen Text repräsentiert wird, gar nicht erst durchgelassen wird.
-
WTF schrieb:
Ich hätte ja auch nichts dagegen gehabt, wenn der +-Operator noch Überladungen für die Grunddatentypen, Zahlen und char (bool wäre da schon wieder irgendwie unpassend), hätte. Aber das sollte es auch schon gewesen sein. object ist da definitiv unpassend. Oder wann wäre zu erwarten, dass ich ein Objekt vom Typ Thread oder Button an einen String anhänge, ohne dass die implizite Konvertierung ein Gedankenfehler ist? Nach dieser Logik wundere ich mich, dass man nicht auch jedes beliebige Objekt auf ein int addieren kann und er dann einfach GetHashCode nimmt.
Es gibt hier keine implizite Umwandlung nach String, sondern einen implizieten Aufruf der ToString() methode die durch Object definiert ist und die JEDES Object in C# hat. Es gibt auch keinen Unterschied zwischen Grundtypen und Klassen so wie in C++. Ein int ist ebenso ein Object wie ein String.
Dein Gedankenfehler liegt in der (falschen) Annahme das es sich um implizite Konvertierungen handelt die aber nicht passieren.
Wenn man schreibt:
String x = "Hallo " + 5;
Dann wird 5 nicht nach String konvertiert, sondern es wird (5).ToString() aufgerufen.
String x = "Hallo " + (5).ToString();
Das passiert immer automatisch sobald bei einer Addition ein String im Spiel ist.
Deine Idee, man könne ja ebenso mehrere +operatoren des String mit entsprechenden Basistypen überladen ist wiede rein klarer Beweis das Du zu shr C++ denkst udn zu wenig C#.
Tipp: Setz Dich mal mit dem Konzept des SOM (Singlerooted Object Model) auseinander, denn anderes als C++ folgt C# diesem Ansatz.
-
WTF schrieb:
Eine Funktion, die nicht mit object überladen ist, damit das Anhängen eines Datentyps, der normalerweise nicht durch einen geschriebenen Text repräsentiert wird, gar nicht erst durchgelassen wird.
Für alle Objekte in C# gibt es eine Repräsentation durch geschriebenen Text weil für alle Objekte die ToString() methode existiert. Dies _ist_ der Normalfall.
-
loks schrieb:
Es gibt hier keine implizite Umwandlung nach String, sondern einen implizieten Aufruf der ToString() methode die durch Object definiert ist und die JEDES Object in C# hat.
Bist du sicher, dass hier wirklich ein impliziter Aufruf stattfindet und es nicht ganz primitv so ist, dass die Implemetierung des +-Operators (denn auch hinter dem steckt ja letztendlich nur eine gewöhnliche Funktion) das ToString aufruft?
public static string operator + (string str, object obj) { MachIrgendwasMitStUndAddiere obj.ToString(); }
loks schrieb:
Tipp: Setz Dich mal mit dem Konzept des SOM (Singlerooted Object Model) auseinander, denn anderes als C++ folgt C# diesem Ansatz.
Google liefert zu "Single Rooted Object Model" ganze drei Treffer. Wie lautet der Name also wirklich?
loks schrieb:
Für alle Objekte in C# gibt es eine Repräsentation durch geschriebenen Text weil für alle Objekte die ToString() methode existiert. Dies _ist_ der Normalfall.
Ja, aber in den meisten Fällen gibt dieses ToString einfach nur den Klassennamen zurück. Ich weiß nicht, ob es da gerechtfertigt ist, dass man alles an einen String anhängen kann. Zumal der Typname ja nicht einmal Objektinformation, sondern generelle Klasseninformation ist. Es gibt auch für jedes Objekt einen Hashcode, trotzdem lässt sich int nicht mit object addieren.
-
WTF schrieb:
Google liefert zu "Single Rooted Object Model" ganze drei Treffer. Wie lautet der Name also wirklich?
Zu SOM im Zusammenhang mit C# habe ich nur etwas gefunden:
Self Organising MapsWTF schrieb:
Es gibt auch für jedes Objekt einen Hashcode, trotzdem lässt sich int nicht mit object addieren.
Sollte man auch nicht können. Hat sicher seine Gründe, dass jedes Objekt einen String repräsentieren kann. Kann mir da viele nützliche Zwecke vorstellen. Allerdings noch zwei Dinge:
1. Wenn man direkt mit Object arbeiten muss, stimmt im Normalfall so oder so etwas mit dem Design nicht.
2. Du kannst theoretisch auch an ein Stück Fleisch einen Text anhängen. Da gibt's einige Möglichkeiten.
-
WTF schrieb:
loks schrieb:
Tipp: Setz Dich mal mit dem Konzept des SOM (Singlerooted Object Model) auseinander, denn anderes als C++ folgt C# diesem Ansatz.
Google liefert zu "Single Rooted Object Model" ganze drei Treffer. Wie lautet der Name also wirklich?
Single Rooted Object Model. Sorry das ich mein Wissen auch aus klassischen Büchern beziehe. Es bedeuted nichts anderes als das alle Klassen von einer gemeinsamen Basisklasse (im Falle von C# object) erben. C++ hat das nicht, bei Java wurde es halbherzig eingeführt, existieren tut das Konzept sein Smalltalk und C# hat es konsequent umgesetzt, hier ist alles ein Objekt.
-
loks schrieb:
Es bedeuted nichts anderes als das alle Klassen von einer gemeinsamen Basisklasse (im Falle von C# object) erben. C++ hat das nicht, bei Java wurde es halbherzig eingeführt, existieren tut das Konzept sein Smalltalk und C# hat es konsequent umgesetzt, hier ist alles ein Objekt.
Tja, gut, alles ist ein Objekt. Aber das bedeutet noch lange nicht, alles ist ein String. Es hat zwar jede Klasse die ToString-Methode sowie einige weitere grundlegende Funktionen. Aber das rechtfertigt für mich immer noch nicht, dass man jedes Objekt an einen String heften kann und der dann implizit ToString aufruft. Zumal das nur bei der Verkettung mit einem vorhandenen String geht, nicht aber bei der generellen Neuzuweisung eines Strings:
string s = "..." + new object(); // Funktioniert. string s = new string(new object()); // Funktioniert nicht.
Zumal in der ToString meistens sowieso nur der Klassenname, also eine systeminterne Information, steht.
Somit seh ich, ehrlich gesagt, nicht den Zusammenhang zwischen dem Prinzip, dass alles ein Objekt ist, und der Idee, speziell bei der Stringaddition (aber nicht bei der Stringzuweisung!) jegliche Typen zuzulassen und dann die ToString-Methode zu nehmen. Auch hat die Idee, dem Objekt eine ToString-Methode zu geben, nichts mit dem Single Rooted Object Model zu tun. Zufälligerweise hat C# beides gemacht: SROM und eine ToString-Methode in object. Aber an sich sind das doch zwei paar Schuhe. Man könnte SROM auch anwenden, ohne dass object ein ToString besitzt. Somit kann man diesen merkwürdigen Additionsoperator in string, der ein object statt einen string entgegen nimmt, nicht mit SROM begründen. Weil alles auch dann noch ein Objekt wäre, wenn object keine ToString-Funktion hätte.
Wie gesagt, man kann ja auch nicht jeden Typen auf int addieren. Und das, obwohl GetHashCode noch viel eher ein einzelnes Objekt repräsentiert als ToString, welches, wenn es nicht überschrieben wird, nur Informationen zur Klasse liefert.
-
WTF schrieb:
loks schrieb:
Es bedeuted nichts anderes als das alle Klassen von einer gemeinsamen Basisklasse (im Falle von C# object) erben. C++ hat das nicht, bei Java wurde es halbherzig eingeführt, existieren tut das Konzept sein Smalltalk und C# hat es konsequent umgesetzt, hier ist alles ein Objekt.
Tja, gut, alles ist ein Objekt. Aber das bedeutet noch lange nicht, alles ist ein String. Es hat zwar jede Klasse die ToString-Methode sowie einige weitere grundlegende Funktionen. Aber das rechtfertigt für mich immer noch nicht, dass man jedes Objekt an einen String heften kann und der dann implizit ToString aufruft. Zumal das nur bei der Verkettung mit einem vorhandenen String geht, nicht aber bei der generellen Neuzuweisung eines Strings:
string s = "..." + new object(); // Funktioniert. string s = new string(new object()); // Funktioniert nicht.
Zumal in der ToString meistens sowieso nur der Klassenname, also eine systeminterne Information, steht.
Somit seh ich, ehrlich gesagt, nicht den Zusammenhang zwischen dem Prinzip, dass alles ein Objekt ist, und der Idee, speziell bei der Stringaddition (aber nicht bei der Stringzuweisung!) jegliche Typen zuzulassen und dann die ToString-Methode zu nehmen. Auch hat die Idee, dem Objekt eine ToString-Methode zu geben, nichts mit dem Single Rooted Object Model zu tun. Zufälligerweise hat C# beides gemacht: SROM und eine ToString-Methode in object. Aber an sich sind das doch zwei paar Schuhe. Man könnte SROM auch anwenden, ohne dass object ein ToString besitzt. Somit kann man diesen merkwürdigen Additionsoperator in string, der ein object statt einen string entgegen nimmt, nicht mit SROM begründen. Weil alles auch dann noch ein Objekt wäre, wenn object keine ToString-Funktion hätte.
Wie gesagt, man kann ja auch nicht jeden Typen auf int addieren. Und das, obwohl GetHashCode noch viel eher ein einzelnes Objekt repräsentiert als ToString, welches, wenn es nicht überschrieben wird, nur Informationen zur Klasse liefert.Ach fick Dich doch ins Knie. Schwachmaten wie Du sind eigendlich die Zeit nicht wert die solche Postings bringen...
-
Erstemal das ich die Kritik von WTF gar nicht sooo doof fand.
Ich weiss zwar nicht wie man da Probeme mit kriegen kann, aber das der +Op. Object annimmt, ist eigentlich wirklich...mmmh..ich sag mal überflüssig.
Wenn man den Programmierer zwingen würde da selber ein ToString() einzufügen, wäre das auch okay gewesen.
-
Hallo,
Vielleicht kann ich zur allgemeinen Verwirrtheit nen bissle was beitragen
Die Stringklasse definiert überhaupt gar keinen Additionsoperator.
Alle schimpfen hier über das Verhalten eines Operators den es gar nicht gibt...
Der Compiler ersetzt alle Vorkommen von + einfach durch Aufrufe der Funktion String.Concat. Das ist ein reines Compilerfeature. Und String.Concat erlaubt nunmal, wie es in der Doku steht, das Zusammenfügen von String + der Stringrepräsentation von Objects. Von daher ist das Verhalten zumindest nicht unerwartet da es genau so in der Doku beschrieben ist.Die Frage nach dem "Warum?" kann man natürlich trotzdem stellen.
Eine Sache ist die, dass Operanden von Operatoren vertauschbar sein sollten. Also objectO + stringS sollte ebenso möglich sein wie stringS + objectO. Das hieße aber, dass für Object ein + Operator definiert werden muss der Strings akzeptiert. Das müsste man auch für alle anderen vorstellbaren Datentypen machen. Das das kaum sinnvoll ist weil dadurch die Basisklasse von abgeleiteten Klassen abhängig wird sollte einleuchten. Totzdem ist es in manchen Situationen schöner Strings mit Objects zu addieren ohne ToString() manuell aufrufen zu müssen. Also bedient man sich der, in der String Klasse vorhandenen, Concat Funktion und umgeht damit das Problem in Object Operatoren definieren zu müssen.
Es kam auch die Frage auf warum die String Klasse keinen Konstruktor hat der Objects annimmt. Gegenfrage: Was sollte der machen was ToString() nicht macht? Wie schon von anderen gesagt existiert ToString in jeder klasse durch Object als Basis aller klassen und von daher ist so ein Konstruktor einfach unnötig.
-
loks schrieb:
...
Unabhängig davon, das WTF auf ein Feature rumreitet das er nicht ändern können wird, muss man wirklich nicht beleidigend werden.
-
loks schrieb:
Ach fick Dich doch ins Knie. Schwachmaten wie Du sind eigendlich die Zeit nicht wert die solche Postings bringen...
Juhu, ich hab die Diskussion gewonnen!
ωτƒ ι∫ ∫τιζζ τεΠ ΛΛ-α-π
man: WTF
lol lol lol lol lol
is old
was created as a half-ass job
is just worse C# code
:p [][/]
[e]Theta[/e] [e]Psi[/e] [e]cap[/e]-| --> Neptun [e]int[/e] | [e]asymp[/e][e]asymp[/e][e]asymp[/e]
Und jetzt verrate ich euch noch was: Das ganze war nur inszeniert. loks und ich, wir sind dieselbe Person.
pwned you all, you b00ns and 1337-hax0rs and/ |/ |´\ | |´\ --- |/ | |\ |\ | |´ / \ | |_/ | |_/ | | | | | | | | |- \ / |\ | \ | | | |\ | |/ |/ | |_ /
-
Schon Scheiße wenn man keine Freunde hat die mit einem spielen und man muss hier Rollenspiele veranstalten.
Eine Selbsthilfegruppe wäre bestimmt nicht das schlechteste für Dich (Euch).
Habt ihr beide schon mal darüber nachgedacht?Setzte euch doch nochmal zusammen und redet mal darüber…
Aber zum andern Thema.
Ist mir damals in meiner Laufbahn zu Basic auch sauer aufgestoßen.textBox = "Text"
Funzt…?
Es wird an Text oder damals noch „Caption“ übergeben.
Leb halt damit...
Tschüß
Wünsch Euch beiden noch einen schönen Tag und geht mal wieder ein Bier zusammen trinken und redet mal wieder über alte Zeiten.
-
Doug_HH schrieb:
Wünsch Euch beiden noch einen schönen Tag und geht mal wieder ein Bier zusammen trinken und redet mal wieder über alte Zeiten.
Irgendwie fällt mir dazu nur ein: 9 von 10 Stimmen in meinen Kopf meinen, das ich nicht verrückt bin, die 10te pfeift...
-
Kindergarten