Unterschied zwischen "string-Typ" und "String-class" bzw. "int-typ" und "Int32-class&



  • Guten Morgen Allerseits,

    ich schau mir momentan bischen C# an , und beschätige mich mit den verschieden Typen. Nun gibts es std. Typen und Typ Klassen

    hier einige:

    Typ Klasse
    --------------------
    string String
    bool Boolean
    short Int16
    uint UInt32

    etc.

    Was ist denn der Unterschied, wann sollte ich die Klassen und wann die Typen verwenden?



  • string == System.String
    uint == System.UInt32
    short == System.Int16
    int == System.Int32
    long == System.Int64
    bool == System.Boolean

    ziemlich egal ob du das linke oder das rechte nimmst, verweist beides auf die selbe klasse

    tipp ewinfach mal in visual studio "string" ein und bleibt mit der maus drueber, im tooltip siehst du dann das es nur ein verweis auf System.String ist

    kurz gesagt, es gibt keine "standard-typen" wie du es nennst - alles ist eine klasse



  • Genau. Im Gegensatz zu Java, wo es wirklich Unterschiede zwischen den einfachen Datentypen und den Wrapperklassen gibt, ist das hier nichts weiter als eine Art typedef.



  • C#ava schrieb:

    Genau. Im Gegensatz zu Java, wo es wirklich Unterschiede zwischen den einfachen Datentypen und den Wrapperklassen gibt, ist das hier nichts weiter als eine Art typedef.

    Zum Glück, ich hasse es, wie diese Sache in Java "gelöst" wurde! 😮



  • Mr Evil schrieb:

    kurz gesagt, es gibt keine "standard-typen" wie du es nennst - alles ist eine klasse

    Das ist soo nicht ganz richtig. int, string, double, etc. sind die im C# Sprachstandard definierten Typen, die haben erstmal gar nichts mit den .Net Klassen zu tun, da die Sprache C# völlig unabhängig von .Net definiert ist.
    Aber im Microsoft .Net Framework werden diese Typen durch die genannten Klassen im System Namespace implementiert und für den Compiler ist int und Int32 das gleiche. Mono macht genau das gleiche weil es kompatibel zur Microsoft Implementation sein will, aber es wäre technisch möglich nen C# Compiler zu schreiben der nicht mit dem .Net Framework arbeitet und daher auch kein Int32 etc. hat, sondern nur int.

    In der Praxis macht das momentan keinen Unterschied, aber sagen dass string und System.String das Gleiche sind kann man auch nicht.



  • um das thema nochmal kurz auf zu greifen

    was ist eigentlich euer favorit ?
    schreibt ihr lieber "string" oder "String" - "int" oder "Int32" ?

    ich hab hier projekte von kolegen rum liegen welche alles bunt gemischt hat

    string bla = String.Empty;
    usw usf

    ist fuer mein teil hab bisher immer "string" und "int" geschrieben, vermutlich da ich aus der c++ ecke komm #gg

    bin aber am ueberlegen String zu verwenden, da meine eigenen objekte dann in der selben farbe sind und die funktions parameter dann nicht immer unterschiedlich bunt sind

    vorher wollte ich aber wissen was sich bei euch am besten macht...



  • Nun, ob du string oder System.String schreibst, spielt wirklich keine Rolle. In manchen Situationen könnte es aber eine Rolle spielen, dass int wirklich ein System.Int32 ist (siehe z.B. Interoperation mit nativen Schnittstellen); da finde ich es jeweils klarer, die Klasse direkt zu verwenden. Alles in allem habe ich aber leider kein echtes System in C#. In C++/CLI hingegen habe ich mir angewöhnt, für .NET nahe Dinge auch die CTS-Typen direkt zu verwenden (teilweise hat man ja auch keine andere Wahl. Es gibt ja keinen direkten Namen für System::String ...). Für den Rest dann "normale" Typen wie int oder in vielen Fällen auch typedef s.

    MfG



  • Hallo.

    Interessanter Beitrag hier!

    Habe auch noch eine Frage. Wo liegt hier der Unterschied:

    --------------------------

    UInt32 ui = new UInt32();
                ui = 15;
                MessageBox.Show(ui.ToString());
    
                UInt32 ui2 = 16;
                MessageBox.Show(ui2.ToString());
    

    --------------------------

    Macht es einen Unterschied wo der Speicher allokiert wird?
    Bzw. wo ist der Unterschied?

    Gruß



  • In C# ist new UInt32 keine Allokation von Speicher, sondern ein Aufruf des Konstruktors von UInt32 .



  • Und wo wäre dann der Unterschied zwischen den Beiden?

    Ich bin eigtl. schon davon ausgegangen das wenn ich ein Objekt erstelle (und das mache ich ja, wenn ich einen Konstruktor aufrufe, der meine Standardwerte setzt),
    z.B. DateTime dt = new DateTime();
    dass ich damit Speicher auf dem Heap allokiere.

    Gruß



  • Alles was Klassen in C# angeht, werden alle meistens mit new erzeugt und somit auch auf dem Heap angelegt.



  • Hallo nochmal..

    aber was wäre dann hier der Unterschied?

    UInt32 ui = new UInt32();
                ui = 15;
                MessageBox.Show(ui.ToString());
    
                UInt32 ui2 = 16;
                MessageBox.Show(ui2.ToString());
    

    Gruß



  • Firefighter schrieb:

    Alles was Klassen in C# angeht, werden alle meistens mit new erzeugt und somit auch auf dem Heap angelegt.

    Falsch. In C# kannst du nicht direkt ein UInt32 auf dem Heap anlegen. Eine Zuweisung " = new UInt32();" entspricht einem Defaultkonstruktoraufruf und erzeugt somit eine 0, aber nicht auf dem Heap, sondern auf dem Stack.

    GaDgeT schrieb:

    Hallo nochmal..

    aber was wäre dann hier der Unterschied?

    UInt32 ui = new UInt32();
                ui = 15;
                MessageBox.Show(ui.ToString());
    
                UInt32 ui2 = 16;
                MessageBox.Show(ui2.ToString());
    

    Gruß

    Nach was für einem Unterschied suchst du denn? Abgesehen davon, dass es sowieso zu

    MessageBox.Show(15.ToString());
    MessageBox.Show(16.ToString());
    

    optimiert wird, ist die erste Zeile äquivalent zu UInt32 ui = 0; .

    MfG



  • /rant/ schrieb:

    Firefighter schrieb:

    Alles was Klassen in C# angeht, werden alle meistens mit new erzeugt und somit auch auf dem Heap angelegt.

    Falsch. In C# kannst du nicht direkt ein UInt32 auf dem Heap anlegen. Eine Zuweisung " = new UInt32();" entspricht einem Defaultkonstruktoraufruf und erzeugt somit eine 0, aber nicht auf dem Heap, sondern auf dem Stack.

    GaDgeT schrieb:

    Hallo nochmal..

    aber was wäre dann hier der Unterschied?

    UInt32 ui = new UInt32();
                ui = 15;
                MessageBox.Show(ui.ToString());
    
                UInt32 ui2 = 16;
                MessageBox.Show(ui2.ToString());
    

    Gruß

    Nach was für einem Unterschied suchst du denn? Abgesehen davon, dass es sowieso zu

    MessageBox.Show(15.ToString());
    MessageBox.Show(16.ToString());
    

    optimiert wird, ist die erste Zeile äquivalent zu UInt32 ui = 0; .

    MfG

    Ahhh ich sehs grad in der spezifikation, tut mir leid, mein Fehler. Ich war woanders mit meinen Gedanken. danke /rant/



  • Hallo!

    Mich würde nun schon genauer interessieren, wann etwas auf dem Heap und wann auf dem Stack angelegt wird.

    Ich dachte nämlich auch auf dem Heap.

    Welche Spezifikation hast du angesprochen, Firefighter?

    Wo ist denn das genauer erklärt, /rant/?

    Wäre sehr dankbar für weitere Infos!

    Gruß



  • Freut mich, dass du genauer wissen willst, was denn nun Sache ist 👍

    GaDgeT schrieb:

    Mich würde nun schon genauer interessieren, wann etwas auf dem Heap und wann auf dem Stack angelegt wird. Ich dachte nämlich auch auf dem Heap.

    Als Faustregel kann man sagen, dass in C# struct s per new immer auf dem Stack erstellt werden (was nicht heisst, dass sie danach nicht doch irgendwo auf dem Heap gespeichert werden können, so etwa als Bestandteil einer anderen Klasse.). struct s sind intern Klassen, welche von System.ValueType erben. Alle Klassen, welche das nicht tun (sprich: class -Typen), werden von C# als so genannte Referenztypen behandelt. Für dich heisst dies, dass du implizit immer eine Referenz auf einen solchen Typen deklarierst, wenn du dessen Namen benutzt zur deklaration einer Variablen benutzt. So ist eine Variable vom Typ object in C# ist ein Wirklichkeit ein *Handle, welches sich auf dem Stack befinden kann, auf ein System.Object *, welches sich seinerseits aber immer auf dem verwalteten Heap befinden muss. Diese Typen werden daher bei einem Aufruf von new jeweils auf dem Heap allokiert. Die Tatsache, dass rein syntaktisch keine Unterscheidung vorgenommen wird, ärgert mich in C# fast am meisten (und ist mit ein Grund, warum ich C++/CLI bevorzuge. Dort werden alle diese Dinge explizit unterschieden, was für den Zweck der Sprache auch nötig ist :D).

    Um es noch weiter zu verkomplizieren gibt es auch noch das so genannte Boxing, wo Werttypen (nicht vergessen, System.ValueType ;)) nach object oder einer bestimmten Schnittstelle (beides keine struct s...) konvertiert werden. Vielleicht ist dir bereits einmal aufgefallen, dass man einer Variable vom Typ object alles zuweisen kann, struct s eingeschlossen. Beim Boxing wird wird ein solches struct auf den Heap verschoben, bzw. gleich dort erstellt.

    // C# Boxing
    object foo = new UInt32(); // UInt32 ist ein struct, und dennoch wird es hier direkt auf den Heap verfrachtet.
    

    MfG 🙂


Log in to reply