Forum: PC-Programmierung C# - by reference / by value an Funktion?


von Mathias _. (mathias1988)


Lesenswert?

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;
    }
}

von Tilo R. (joey5337) Benutzerseite


Lesenswert?

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.

von cppbert (Gast)


Lesenswert?

Objects immer als Referenz
Structs immer als Value

von re (Gast)


Lesenswert?

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)

von Mathias _. (mathias1988)


Lesenswert?

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 :)

: Bearbeitet durch User
von cppbert (Gast)


Lesenswert?

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

von re (Gast)


Lesenswert?

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.

von Tilo R. (joey5337) Benutzerseite


Lesenswert?

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.

von Mathias _. (mathias1988)


Lesenswert?

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

von h4x0r (Gast)


Lesenswert?

Mathias _. schrieb:
> ich habe die ersten Schritte in C# gewagt

Mein Freund, du bist auf dem falschen Pfad! Kehre um und wähle den 
richtigen Weg (C++). Noch ist es nicht zu spät.

von WS (Gast)


Lesenswert?

Quatsch, immer diese Arroganz der sogenannten C und C++ Kenner.
Sind nicht in der Lage über ihren Tellerrand zu schauen.

von h4x0r (Gast)


Lesenswert?

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.

von Jens (Gast)


Lesenswert?

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!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.