Instanzen und Referenzen - wann dies, wann das?



  • Hallo zusammen!

    Ich blicke einfach nicht durch, wann man in C# eine Referenz erhält und wann eine neue Instanz!

    Hier mal ein einfaches Codebeispiel:

    String str = StringList[2];
    

    Dabei soll StringList:

    List<string> StringList = new List<string>();
    

    Ist str nun eine Referenz oder eine Instanz?

    Hoffe man versteht, was ich meine.

    Grüße
    veryxRV



  • Hallo, ich glaube, Du stellst Dir unter den Begriffen einfach etwas falsches vor.

    Eine Instanz hast Du, sobald Du von einem Typ ein Exemplar erzeugst. D.h. mit jeder Variablen und jeder Konstanten in Deinem Code ist eine Instanz assoziiert (außer dann, wenn es null ist). Außerdem erzeugt jede Berechnung und jede Funktionsrückgabe eine neue Instanz von irgendwas.

    Eine Referenz hat damit erst mal nichts zu tun, das ist etwas ganz anderes. Referenzen sind Variablen, welche auf ein Objekt eines Referenztypen zeigen. Referenztypen in C# sind Typen, die Klassen sind. Auf der anderen Seite gibt es Wertetypen, die als Typ nicht eine Klasse sondern ein Struct oder ein Enum haben.

    In Deinem Fall:

    Ist str nun eine Referenz oder eine Instanz?

    Beides. 'str' ist eine Instanz, weil es einen Wert enthält.
    Es ist außerdem eine Referenz, weil die Variable vom Typ 'String' ist, und 'String' ist ein Referenztyp.

    /EDIT: genauer gesagt verweist 'str' auf eine Instanz (weil es eben eine Referenz ist), aber das ist ein Detail.



  • Okay, dann habe ich da eine völlig falsche Vorstellung 🙂 Ich denke einfach zu sehr in C++ mit Pointern etc.

    Ist denn

    String str = List[2];
    str = "hallo";
    

    dasselbe wie

    List[2] = "hallo";
    

    ???



  • veryxRV schrieb:

    Ist denn

    String str = List[2];
    str = "hallo";
    

    dasselbe wie

    List[2] = "hallo";
    

    ???

    Nein. Im ersten Code weist Du 'str' nacheinander zwei unterschiedliche Referenzen zu. Wenn Du zu sehr in C++ denkst, dann stell Dir die obigen Codes einfach folgendermaßen in C++ vor:

    string* str = list[2];
    str = new string("Hallo");
    // vs.
    list[2] = new string("Hallo");
    

    Die Codes sind offensichtlich nicht dieselben. Was Du wahrscheinlich dachtest, ist folgendes:

    string* str = list[2];
    *str = static_cast<string>("Hallo");
    

    Hier ist offensichtlich, dass Du nicht 'str' einen neuen Wert zuweist, sondern dem Inhalt von 'str', also dem, worauf 'str' zeigt.



  • Danke, das wollte ich wissen! 🙂

    Und wie setze ich dann letzteres in C# um?



  • veryxRV schrieb:

    Danke, das wollte ich wissen! 🙂

    Und wie setze ich dann letzteres in C# um?

    Gar nicht. In C++ wird hier nämlich operator = für die 'string'-Klasse aufgerufen und der Inhalt des Strings ändert sich.

    Strings sind in C# aber immutable, d.h. ihr Inhalt kann nicht geändert werden. Jedes Mal, wenn man einen String modifiziert, erstellt man in Wahrheit einen neuen.

    Abgesehen davon kann man zwar Operatoren allgemein überladen, den Zuweisungsoperator hingegen nicht.


Anmelden zum Antworten