Hier geht es um zwei dichotome Themen mit ähnlichem Vokabular: Wert versus Referenz Typen und die Übergabe Variablen nach Wert und nicht nach Verweis.
Wert- vs. Referenztypen
Die erste Frage ist Wert versus Referenz Typen . Werttypen werden durch Kopieren weitergegeben - normalerweise. Die Wertetypen sind:
- Datum
- Char
- U/Int(16/32/64)
- Dezimal
- Einzel und Doppel
- Boolesche
- Strukturen
- Enums
Mit Ausnahme der oben aufgeführten Typen sind alle Typen Referenztypen. Wenn ein Objekt weitergegeben wird, wird eigentlich seine Speicheradresse weitergegeben, die auf 32-Bit-Plattformen oft als int und auf 64-Bit-Plattformen als long bezeichnet wird.
Übergabe nach Wert vs. nach Referenz
Das zweite Problem ist die Übergabe eine Variable nach Wert versus Referenz.
Eine Variable ist ein Steckplatz an einer bestimmten Position im Speicher, der Dinge aufnehmen kann. Bei Werttypen enthält sie den eigentlichen Wert. Bei Referenztypen enthält sie die Speicheradresse des Objekts auf dem Heap (oder ist Nothing).
Nach Wert
Wenn Sie eine Variable als Wert übergeben, wird das kopiert, was sich an der Speicherposition dieser Variable befindet. Bei Werttypen bedeutet dies, dass der Wert selbst kopiert wird. Bei Referenztypen wird die Speicheradresse des Objekts kopiert, auf das sich die Variable bezieht.
Nach Referenz
Erinnern Sie sich daran, dass eine Variable nur ein Speicherplatz ist, in dem Sie etwas speichern können. Wenn Sie eine Variable per Referenz übergeben, übergeben Sie die Adresse dieses Steckplatzes (im Gegensatz zu den Daten in diesem Steckplatz).
Handelt es sich bei der Variablen um einen Werttyp, enthält dieser Steckplatz den Wert selbst, so dass das übergebene Element ein Zeiger auf den Wert ist.
Wenn es sich bei der Variablen um einen Referenztyp handelt, enthält der Slot einen Zeiger auf den Speicherplatz des Objekts. Das, was übergeben wird, ist also ein Zeiger auf Ihre Variable (genau wie bei Werttypen), die ihrerseits einen weiteren Zeiger enthält (nicht wie bei Werttypen), der zu dem Speicherplatz führt, an dem sich das Objekt befindet, auf das die Variable verweist.
Damit kann eine Funktion eine Variable in einer anderen Funktion ändern, etwa so:
Sub IPassByReference
Dim myVariable As Boolean = False
IReceiveByReference myVariable
Debug.Print(myVariable.ToString()) 'Always prints True
End Function
Sub IReceiveByReference(ByRef flag As Boolean)
flag = True 'the memory address of myVariable was passed.
End Function
Vergleichen wir dies mit der Situation, in der Sie nach Wert übergeben:
Sub IPassByValue
Dim myVariable As Boolean = False
IReceiveByValue myVariable
Debug.Print(myVariable.ToString()) 'Always prints False
End Function
Sub IReceiveByValue(ByVal flag As Boolean)
flag = True 'the value of myVariable was passed.
End Function
Im obigen Beispiel ist Boolean ein Wertetyp. Wäre es ein Objekt, hätte IReceiveByReference die Möglichkeit, myVariable auf ein völlig neues Objekt zu verweisen, da es die Adresse von myVariable erhalten hat - nicht die Adresse des Objekts, auf das myVariable verweist. Im Gegensatz dazu wurde IReceiveByValue nur der Inhalt von myVariable übergeben, so dass es myVariable nicht ändern kann, um auf ein neues Objekt zu zeigen. Es könnte das Objekt aber immer noch ändern, indem es seine Felder und Eigenschaften setzt und seine Methoden aufruft.
By-Referenz zurückgeben?
Obwohl Funktionen Variablen per Referenz übergeben können, können sie sie nicht auf diese Weise zurückgeben. Wenn eine Funktion zurückkehrt, sind ihre lokalen Variablen nicht mehr vorhanden (oder stehen zur Bereinigung an, wenn sie auf dem Heap alloziert sind). Funktionen kehren daher immer als Wert zurück, da die lokalen Variablen keine gültigen Speicheradressen mehr haben, es gibt keine Variablenreferenzen, die zurückgegeben werden müssen .
Zusammenfassend lässt sich sagen, dass bei der Rückgabe eines Objekts aus einer Funktion nur die Adresse des Objekts kopiert wird. Wenn Sie eine Wertart aus einer Funktion zurückgeben, wird der Wert selbst kopiert.
Das bedeutet, dass Referenztypen im Wesentlichen Werttypen sind, wobei der Wert die Speicheradresse eines Objekts auf dem Heap (oder Nothing) ist.