string
-
Das hat garnichts mit der Typsicherheit zu tun. Jedes Objekt kann zu einem String konvertiert werden, das ist so festgelegt und da ist nichts falsches dran...
Wenn du ein Problem mit .NET hast, dann benutz es doch einfach nicht.
-
David_pb schrieb:
Das hat garnichts mit der Typsicherheit zu tun. Jedes Objekt kann zu einem String konvertiert werden, das ist so festgelegt und da ist nichts falsches dran...
Explizit wäre es in Ordnung. Aber implizit? Ich hatte ursprünglich eine string-Variable, die ich in eine Datenbank schreibe. Dann hab ich aus dem String im Programm eine richtige Klasse gemacht. Jetzt, ein halbes Jahr danach, bekam das Programm einen Bug, weil die ToString-Funktion umgeschrieben wurde und nun nicht mehr nur das in die Datenbank zu Schreibende zurück gibt, sondern einen kompletten, ausgeschriebenen Namen. Und einige Strings wurden immer noch mit Objekten dieser Klasse addiert. Hätten die .Net richtig gemacht, hätte mir der Compiler damals schon gesagt, dass man ein Objekt von meiner Klasse nicht auf einen String addieren kann und ich hätte gleich MeinString += MeinObjekt.ID geschrieben.
-
Ich seh schon was du meinst und man kann sich mit sicherheit auch darüber streiten, warum Object eine ToString() Methode hat. Aber, dass ist nicht das Problem von String.
-
David_pb schrieb:
Ich seh schon was du meinst und man kann sich mit sicherheit auch darüber streiten, warum Object eine ToString() Methode hat. Aber, dass ist nicht das Problem von String.
Dass object eine ToString-Methode hat, ist nicht mein Problem. Gegen explizite Konvertierungen hab ich nichts. Mich stört nur, dass der +-Operator von string objects entgegennehmen kann. Das hätte nicht sein müssen. Den hätte man so programmieren können, dass er ausschließlich strings entgegennimmt. Wenn ich einen String mit einem Objekt verbinden möchte, könnte ich ja dann das ToString benutzen. Aber dass so etwas implizit funktioniert, ist eben Dreck. Oder gibt es einen sinnvollen Anwendungsbereich, wo die implizite Konvertierung von allen Objekten in string Sinn macht? ToString gibt per default sowieso nur den Klassennamen zurück, und der geht den Benutzer ja letztendlich gar nichts an. Und wenn man eben in ToString etwas Sinnvolles stehen hat, kann man auch ToString aufrufen, wenn man es braucht. Oder auch einen implicit operator string deklarieren.
Es ist ja auch nicht so, dass object generell immer implizit in string umgewandelt werden kann. Das hier funktioniert zum Beispiel nicht:
object o = new object(); MessageBox.Show(o);
Und warum nicht? Weil die implizite Umwandlung von object in string eben kein generelles Feature von .Net ist, sondern nur, weil der Parameter des +-Operators von string object ist.
-
WTF schrieb:
Oder gibt es einen sinnvollen Anwendungsbereich, wo die implizite Konvertierung von allen Objekten in string Sinn macht?
Der Debugger zeigt das Ergebnis davon an. Selbstverständlich gehört auch in jeder Klasse ToString() überschrieben.
Anfänger.
-
if (User.Name == "noob camper") { while (true) { User.ReadPost(@"
noob camper schrieb:
Der Debugger zeigt das Ergebnis davon an.
Ooooh, da dann ist es ja gerechtfertigt: Weil der Debugger dann etwas Schönes zum Anzeigen hat. Das ist natürlich ein Grund, eine Programmierentscheidung zu treffen: Wie gut sieht es im Debugger aus?
noob camper schrieb:
Selbstverständlich gehört auch in jeder Klasse ToString() überschrieben.
Ach ja? Interessant, dass die meisten .Net-Klassen das trotzdem nicht tun und nur den Klassennamen anzeigen.
Was würdest du hier für ToString bei einer Klasse, die eine Videospielfigur repräsentiert, vorschlagen?
noob camper schrieb:
Anfänger.
b00n!!!!!!!!!einseinseinself
ωτƒ ι∫ ςσσζεΓ τΠΛπ γσμ.
"); } }
-
Du solltest Dir nochmal die Grundlagen von Net zu Gemüte ziehen, du Mettwurst...
-
Das Problem lässt sich mit parametrisierten SQL-Queries umgehen
-
Merle schrieb:
Du solltest Dir nochmal die Grundlagen von Net zu Gemüte ziehen, du Mettwurst...
Na, dann gib mir mal einen Tipp, wonach ich suchen soll. Grundlagen gibt es viele.
geeky schrieb:
Das Problem lässt sich mit parametrisierten SQL-Queries umgehen
Das mit der Datenbank war nur Hintergrundwissen. Darum ging es nicht. Es ging mehr darum, dass ich folgendes gemacht habe:
string[] meineDaten... for (int i = 0; i < meineDaten.Length; i++) label.Text += meineDaten[i] + ";"; label.Text = label.Text.Trim(';');
Und wenn meineDaten zu einer eigenen Klasse werden, hätte ich eigentlich gehofft, dass mir der Compiler an jeder Stelle, wo sowas vorkommt, einen Fehler liefert, damit ich überall schreiben kann:
MeineKlasse[] meineDaten... for (int i = 0; i < meineDaten.Length; i++) label.Text += meineDaten[i].ID + ";"; label.Text = label.Text.Trim(';');
und nicht implizit den String-Operator nimmt, der ja unter Umständen etwas ganz anderes beinhaltet als das, was ich da auflisten will.
-
WTF schrieb:
Und wenn meineDaten zu einer eigenen Klasse werden, hätte ich eigentlich gehofft, dass mir der Compiler an jeder Stelle, wo sowas vorkommt, einen Fehler liefert, damit ich überall schreiben kann:
[cs]MeineKlasse[] meineDaten...Es ist nicht die Aufgabe des Compilers deine logischen Fehler oder Design Fehler zu finden. Es ist DEINE Aufgabe Klassen so zu designen das solche Fehler entweder gar nciht erst passieren oder z.B. durch Unit Tests gefunden werden können. Also gib nicht dem Compiler die Schuld dafür das Dein Design schwach ist... Versuch lieber aus den Fehlern zu lernen und es beim nächsten Mal besser zu machen...
Ich schätze Du hast früher C++ programmiert und versuchst jetzt im gleichen Stil C# zu proggen (die for-Schleife ist ein deutliches Give-away für Ex-C++ler, jeder C#ler würde hier ne foreach nehmen). Das geht idr schief weil C# eben NICHT C++ ist. Entscheidender Unterschied ist das SOM das C++ bis heute nicht kennt, C# dagegen schon....
-
loks schrieb:
Es ist nicht die Aufgabe des Compilers deine logischen Fehler oder Design Fehler zu finden. Es ist DEINE Aufgabe Klassen so zu designen das solche Fehler entweder gar nciht erst passieren oder z.B. durch Unit Tests gefunden werden können.
Was hat das mit dem Klassendesign zu tun? Hätte ich statt += einfach = genommen, hätte es komischerweise einen Fehler gegeben.
Ich sehe immer noch keinen Grund, auf einen String implizit alles addieren zu können. Nach dieser Logik könnte man auch rechtfertigen, dass man einem int alles übergeben kann und das int dann den string aus der ToString-Methode parst.loks schrieb:
Also gib nicht dem Compiler die Schuld dafür das Dein Design schwach ist...
Das liegt überhaupt nicht am Design, sondern an der fehlenden Typprüfung. Es ist nicht logisch, jeden Datentyp implizit auf einen string aufzuaddieren. Erst recht nicht, wenn die gewöhnliche Zuweisung auch nicht funktioniert. (text = meinObjekt geht nicht, was auch logisch ist, aber text += meinObjekt lässt er zu)
loks schrieb:
Ich schätze Du hast früher C++ programmiert
Und? Das, worum es hier geht, ist lediglich Typsicherheit, und das ist ja wohl in C++ und C# gefragt. Wie gesagt: Man kann kein object implizit in einen int umwandeln, man kann ja nichtmal b = i schreiben wenn b ein byte und i ein int ist. Man kann auch kein object auf einen string belegen. Aber kurioserweise kann man jedes object implizit auf einen string aufaddieren. Danke, .Net, das macht Sinn und ist konsistent!
-
WTF schrieb:
loks schrieb:
Es ist nicht die Aufgabe des Compilers deine logischen Fehler oder Design Fehler zu finden. Es ist DEINE Aufgabe Klassen so zu designen das solche Fehler entweder gar nciht erst passieren oder z.B. durch Unit Tests gefunden werden können.
Was hat das mit dem Klassendesign zu tun? Hätte ich statt += einfach = genommen, hätte es komischerweise einen Fehler gegeben.
Ich sehe immer noch keinen Grund, auf einen String implizit alles addieren zu können. Nach dieser Logik könnte man auch rechtfertigen, dass man einem int alles übergeben kann und das int dann den string aus der ToString-Methode parst.loks schrieb:
Also gib nicht dem Compiler die Schuld dafür das Dein Design schwach ist...
Das liegt überhaupt nicht am Design, sondern an der fehlenden Typprüfung. Es ist nicht logisch, jeden Datentyp implizit auf einen string aufzuaddieren. Erst recht nicht, wenn die gewöhnliche Zuweisung auch nicht funktioniert. (text = meinObjekt geht nicht, was auch logisch ist, aber text += meinObjekt lässt er zu)
loks schrieb:
Ich schätze Du hast früher C++ programmiert
Und? Das, worum es hier geht, ist lediglich Typsicherheit, und das ist ja wohl in C++ und C# gefragt. Wie gesagt: Man kann kein object implizit in einen int umwandeln, man kann ja nichtmal b = i schreiben wenn b ein byte und i ein int ist. Man kann auch kein object auf einen string belegen. Aber kurioserweise kann man jedes object implizit auf einen string aufaddieren. Danke, .Net, das macht Sinn und ist konsistent!
q.e.d
-
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.