In C # habe ich immer gedacht, dass nicht-primitive Variablen als Referenz und primitive Werte als Wert übergeben wurden.
Wenn Sie also ein nicht primitives Objekt an eine Methode übergeben, wirkt sich alles, was mit dem Objekt in der Methode getan wird, auf das übergebene Objekt aus. (C # 101 Zeug)
Ich habe jedoch festgestellt, dass dies beim Übergeben eines System.Drawing.Image-Objekts nicht der Fall zu sein scheint. Wenn ich ein system.drawing.image-Objekt an eine andere Methode übergebe und ein Bild auf dieses Objekt lade, dann lasse diese Methode den Gültigkeitsbereich verlassen und gehe zur aufrufenden Methode zurück. Wird dieses Bild nicht auf das ursprüngliche Objekt geladen?
Warum ist das?
Antworten:
Objekte werden überhaupt nicht übergeben. Standardmäßig wird das Argument ausgewertet und sein Wert als Wert als Anfangswert des Parameters der von Ihnen aufgerufenen Methode übergeben. Der wichtige Punkt ist nun, dass der Wert eine Referenz für Referenztypen ist - eine Möglichkeit, zu einem Objekt (oder Null) zu gelangen. Änderungen an diesem Objekt sind für den Aufrufer sichtbar. Das Ändern des Werts des Parameters, um auf ein anderes Objekt zu verweisen, ist jedoch nicht sichtbar, wenn Sie den Wert "Übergeben" verwenden. Dies ist die Standardeinstellung für alle Typen.
Wenn Sie Pass-by-Referenz verwenden möchten, Sie müssen verwenden
out
oderref
, ob der Parametertyp ein Werttyp ist oder ein Referenztyp. In diesem Fall wird die Variable selbst effektiv als Referenz übergeben, sodass der Parameter denselben Speicherort wie das Argument verwendet - und Änderungen am Parameter selbst vom Aufrufer gesehen werden.So:
Ich habe einen Artikel, der hier viel ausführlicher behandelt wird . Grundsätzlich bedeutet "Referenzübergabe" nicht, was Sie denken, dass es bedeutet.
quelle
ref
undout
von c # entfernen, ist es in Ordnung zu sagen, dass c # Parameter auf die gleiche Weise wie Java übergibt, dh immer nach Wert. Gibt es einen Unterschied zu Java?Ein weiteres Codebeispiel, um dies zu demonstrieren:
Und die Ausgabe:
quelle
Viele gute Antworten wurden hinzugefügt. Ich möchte noch einen Beitrag leisten, vielleicht wird es etwas mehr klarstellen.
Wenn Sie eine Instanz als Argument an die Methode übergeben, wird
copy
die Instanz übergeben. Wenn es sich bei der übergebenen Instanz um einevalue type
(in derstack
) befindliche Instanz handelt, übergeben Sie die Kopie dieses Werts. Wenn Sie sie also ändern, wird sie nicht im Aufrufer angezeigt. Wenn es sich bei der Instanz um einen Referenztyp handelt, übergeben Sie die Kopie der Referenz (befindet sich wieder in derstack
) an das Objekt. Sie haben also zwei Verweise auf dasselbe Objekt. Beide können das Objekt ändern. Wenn Sie jedoch innerhalb des Methodenkörpers ein neues Objekt instanziieren, verweist Ihre Kopie der Referenz nicht mehr auf das ursprüngliche Objekt, sondern auf das gerade erstellte neue Objekt. Sie haben also 2 Referenzen und 2 Objekte.quelle
Ich denke, es ist klarer, wenn du es so machst. Ich empfehle, LinqPad herunterzuladen, um solche Dinge zu testen.
Und das sollte ausgegeben werden
WontUpdate
Vorname: Egli, Nachname: Becerra
UpdateImplicitly
Vorname: Favio, Nachname: Becerra
UpdateExplicitly
Vorname: Favio, Nachname: Becerra
quelle
Wenn Sie das
System.Drawing.Image
Typobjekt an eine Methode übergeben, übergeben Sie tatsächlich eine Referenzkopie an dieses Objekt.Wenn Sie also innerhalb dieser Methode ein neues Bild laden, laden Sie es mit einer neuen / kopierten Referenz. Sie nehmen keine Änderungen am Original vor.
quelle
Wie haben Sie das Objekt an die Methode übergeben?
Tun Sie in dieser Methode für Objekte etwas Neues? Wenn ja, müssen Sie
ref
in Methode verwenden.Der folgende Link gibt Ihnen eine bessere Vorstellung.
http://dotnetstep.blogspot.com/2008/09/passing-reference-type-byval-or-byref.html
quelle
In Pass By Reference Sie fügen nur "ref" in die Funktionsparameter ein und eine weitere Sache, die Sie als "static" deklarieren sollten, da main static (#
public void main(String[] args)
) ist!quelle