string



  • 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 + Operator

    Daraus 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 Maps

    WTF 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.


Anmelden zum Antworten