Objekte als Referenz übergeben wie bei Variablen



  • In der Mainfunktion benutzte ich Objekte. Diese möchte ich einer andere Klasse übergeben. Diese verändert dann z.B. die Member oder Eigentschaften dieser Objekte. Anschließend möchte ich genau dieses Objekt in der Mainfunktion weiter benutzten. Kann ich z.B. Objekte referenzieren wie z.B. Variablen?

    Beispiel

    Diese Klasse benutzt:

    class UserInputHandling
    {
    public AddSymbolconversationProperties(ref ParentPackage, ..., ...)
    {
    ...
    ParentPackage.Name = "BeispielQuellcode";
    ...
    }
    
    }
    

    Die Mainfunktion

    Main()
    {
    ...
    UserInputHandling StringHandling = new UserInputHandling();
    EA.Package ParentPackage = Repository.GetPackageByID(NewPackage.ParentID);
    ...
    //Hier soll das Objekt eingelesen werden und in der Methode verändert
    //werden können. Dannach muss aber die Änderung auch in der Mainfunktion erreibar sein 
    StringHandling.AddSymbolconversationProperties(ParentPackage);
    MessageBox.Show(ParentPackage.Name);//Ausgabe: BeispielQuellcode
    }
    

    Ich bedanke mich bei Euch schon mal im Voraus.



  • Objekte von Klassen werden in C# generell by Ref übergeben, das heißt du kannst dir das ref Keyword sparen



  • Ja genau. So hatte ich das auch im Kopf. Ich war mir nur nicht mehr ganz so sicher.

    Beispiel

    TestClass obj1 = new TestClass(); 
    obj1.name = "TEST1";
    TestClass obj2 = obj1;
    obj2.name = "TEST2";
    
    MessageBox.Show(obj1.name);
    

    Dass würde also heißen, wenn ich das obj2 verändere, so kann ich es auch bei obj1 sehen. Da obj2 auf obj1 referenziert ist oder? Also die Ausgabe der MessageBox wäre dann TEST2 oder?



  • Korrekt.
    Aber das hättest du auch ohne Probleme selber testen können 😉



  • Teste es doch. 🕶



  • Mit dieser Antwort habe ich fast gerechnet.
    Es ist das gleiche Ergebnis. 🙂



  • sventesker schrieb:

    Mit dieser Antwort habe ich fast gerechnet.
    Es ist das gleiche Ergebnis. 🙂

    Falsch. Es ist dasselbe Ergebnis. das gleiche wäre es auch bei zwei unterschiedlichen Objekten mit gleichem Inhalt...



  • Firefighter schrieb:

    Objekte von Klassen werden in C# generell by Ref übergeben, das heißt du kannst dir das ref Keyword sparen

    Falsch. Objekte werden in C# standardmäßig by Value übergeben.
    Allerdings gibt es Referenztypen (Klassen) und Wertetypen (Structs usw).
    Wenn ein Referenztyp als Parameter übergeben wird und ich den Inhalt des Parameters in der Methode ändere, ändert sich auch der Inhalt des Originals (ist im Prinzip wie das schreiben auf eine Adresse in C/C++). Wenn ich dem Parameter selbst einen Wert zuweise, bleibt das Original unverändert.
    Call by Reference bedeutet, dass ich den Parameter selbst (in C/C++ die Adresse) ersetzen kann, und damit auch das Original ersetzt wird.

    class Test
    {
      private string text = "Reference";
    
      static void Main(string[] args)
      {
        Test test1 = new Test();
        CallByValue(test1);
        Console.Out.WriteLine(test1.text); //Ausgabe "Value"
        CallByReference(ref test1);
        Console.Out.WriteLine(test1.text); //Ausgabe "Reference"
      }
    
      public static void CallByValue(Test test)
      {
        test.text = "Value";
        //Hat keinen Effekt auf fas Original, da es sich um eine Kopie handelt.
        test = new Test();
      }
    
      public static void CallByReference(ref Test test)
      {
        test.text = "Value";
        //Der Referenz wird ein neuer Wert zugewiesen, auch das Original ändert sich.
        test = new Test();
      }
    }
    

    Also das "ref"-keyword hat durchaus seine Berechtigung (nicht nur für Value-Types), allerdings brauchst du es in deinem Beispiel nicht, eben weil du "Call by Value" mit einem Referenztyp machst.



  • Ok wenn Objekte von Klassen als Call-By-Value übergeben werden würden, würde das bei dir heißen es würde innerhalb der MEthode eine Lokale Kopie des Objektes angelegt und auf diesen gearbeitet.
    Wenn das so wäre, würden sich aber nicht die Values der Member ändern, das heißt es wird keine Kopie angelegt und somit findet auch kein Call-By-Value statt.

    Edit: Ok habs nochmal nachgelesen, hast Recht. Mir erschien das nur gerade etwas merkwürdig 😉



  • Ja, es wird ja keine Kopie des Objektes angelegt, aber es wird eine neue Referenz auf das Objekt angelegt. Über diese Referenz kann ich dann natürlich das Objekt auch editieren.
    Ist wie gesagt, das gleiche wie wenn ich in C++ eine Methode mit einem Pointer aufrufe (was auch oft fälschlicherweise als Call By Reference bezeichnet wird). Man kann auf das Objekt über den Pointer zugreifen und verändern. Wenn ich allerdings den Pointer als Rückgabewert verwenden will (d.h. ändern, z.B. weil ich mehrere Rückgabewerte brauche), muss eine Referenz auf einen Pointer übergeben werden.
    In C# passiert hinter den Kulissen genau das gleiche (bei Klassen, bei Structs wird ohne das "ref"-Keyword tatsächlich eine Kopie übergeben).


Anmelden zum Antworten