C# - by reference / by value an Funktion?

OP #6223479
Hallo zusammen,

ich habe die ersten Schritte in C# gewagt und bereits eine Frage bzgl. 
der Übergabe von Objekten an Funktionen.

Ändere ich eine Variable eines Objektes innerhalb einer Funktion, so 
wird die Änderung im Objekt abgespeichert. In C "Ohne sharp" 
funktioniert das ja nur, wenn ein Objekt "by reference" also mit Pointer 
an die Funktion übergeben wird.

Jetzt bin ich etwas verwirrt. Wird bei C# ein Objekt nun standardmäßig 
"by reference" oder "by value" an die Funktion übergeben. In der 
Literatur konnte ich "by value" als default nachlesen. Wäre super, wenn 
mir bei dieser Anfängerfrage jemand weiterhilft, wie denn die 
Zusammenhänge sind.

Hier mal ein Beispiel:

namespace UserLoginSystem
{
    class Program
    {
        static void Main(string[] args)
        {
            Human Mathias = new Human();
            Mathias.surename = "Maier";
            Mathias.age = 18;
            Console.WriteLine(Mathias.surename + " age:" + Mathias.age);
            changeHumanName(Mathias, "Wimmer",22);
            Console.WriteLine(Mathias.surename + " age:" + Mathias.age);
            Console.ReadKey();
        }

        static void changeHumanName(Human human,string newname, int 
newage)
        {
            human.surename = newname;
            human.age = newage;
        }
    }

    class Human
    {
        public string surename;
        public int age;
    }
}
Persönliche Seite #6223496
Bei Objekten in C# (und Java) steht in der entsprechenden Variable eine 
Referenz auf das entsprechende Objekt. (Das irgendwo im verwalteten 
Arbeitsspeicher rumliegt, was dich aber nichts angeht.)

Insofern entspricht die Übergabe eines Objekts der C-Denke "by 
reference", weil der Wert der Objektreferenz übergeben wird.
Gast #6223508
In C# ist das bei Objekten standardmäßig "by reference", bei nativen 
Datentypen (int, double, ...) "by-value".

Für "by-value" würde ein Copy-Construktor benötigt werden (wie in C++ ja 
auch) - und damit tut sich C# afaik etwas schwerer als C++ (korrigiert 
mich, wenn ich mit dieser Ve4rmutung falshcliege)

Leider inkonsistent und umständlich, wenn man native Datentypen 
"by-reference" übergeben will.

(re)
OP #6223510
Jetzt wart ihr aber alle schnell :) . Danke für eure Antworten. Dann 
werde ich das mit den nativen Datentypen (int , double ...) auch mal 
ausprobieren. Das heißt, wenn ich diese Datentypen an eine Funktion 
übergebe und darin die variable verändern will muss ich "ref" 
vorranstellen ?

Danke für eure Antworten, es hat mir auf alle Fälle schon geholfen :)
Gast #6223520
Mathias _. schrieb:
> Jetzt wart ihr aber alle schnell :) . Danke für eure Antworten.
> Dann
> werde ich das mit den nativen Datentypen (int , double ...) auch mal
> ausprobieren. Das heißt, wenn ich diese Datentypen an eine Funktion
> übergebe und darin die variable verändern will muss ich "ref"
> vorranstellen ?
>
> Danke für eure Antworten, es hat mir auf alle Fälle schon geholfen :)

out oder inout
Gast #6223521
Mathias _. schrieb:
> die Frage, war um es "by referenence" in C# gibt ?

Bei komplexen Objekten macht was anderes eigeentlich auch nur selten 
Sinn, genauso wie man in C++ sowas auch fast immer "by reference" 
übergibt.


> Ich kann einem Objekt bei der Übergabe ja auch ein "ref" voranstellen..

Das kommt z.B. bei Structs zum tragen, die sonst "by value" übergeben 
werden würden.
Persönliche Seite #6223528
Vielleicht noch ein paar zusätzliche Hinweise:
Das ist nicht so schlecht wie es sich anhört, weil Referenzen ja viel 
kleiner sind als das tatsächliche Objekt im Speicher. Das geht also 
schneller. Und man spart trotzdem das ganze gepointere, referenzieren 
und dereferenzieren.

Trotzdem ergibt sich damit das Problem, dass, sobald du ein Objekt 
irgendjemandem gegeben hast, der das auch ändern kann. Da hilft kein 
const :-)

Wenn sowas ungünstig ist, gibt es 2 Muster, die dagegen helfen:

1. (das Beste) sind immutable-Objekte. Das sind Objekte, deren Member 
alle final sind, d.h. da kann man nichts mehr verändern.

2. Copy-Konstruktoren, dann kann man sein eigenes Objekt behalten.
Ähnlich macht man es, wenn ein immutable-Objekt (wie z.B. string) doch 
bearbeitet werden muss: darum liefert z.B. die ToUpper-Methode einen 
neuen string, statt das existierende Objekt zu verändern.
OP #6223532
Hab es gerade mit "ref int number" für die Übergabe als Referenz 
ausprobiert und es funktioniert feuerwerk :). Ich bin da aus der 
C-Programmierung noch getauft von der Pointerrei und mir ist wichtig zu 
verstehen, wie die Dinge hier bei C# ablaufen. Danke allen für die 
Unterstützung, jetzt kann ich mich weiter reinarbeiten :).

Gruß,
Mathias
Gast #6224156
WS schrieb:
> Quatsch, immer diese Arroganz der sogenannten C und C++ Kenner.

Lieber WS, auch du wirst irgendwann den Irrweg erkennen auf dem du 
wandelst. Du hast dich von einem Dämon und seinen falschen Versprechen 
leiten lassen. Wende dich von ihm ab und kehre zu uns zurück.
Gast #6224230
h4x0r schrieb:
> Lieber WS, auch du wirst irgendwann den Irrweg erkennen auf dem du
> wandelst. Du hast dich von einem Dämon und seinen falschen Versprechen
> leiten lassen. Wende dich von ihm ab und kehre zu uns zurück.

Zurück in deine Höhle, Troll!

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 6 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.