6 Stimmen

VB.NET, Wird ein Objekt durch eine Referenz von einer Funktion zurückgegeben

Diese Frage sollte relativ häufig gestellt werden, aber ich habe nirgendwo eine eindeutige Antwort gefunden.

Wenn ich ein Objekt innerhalb einer Funktion in VB.NET instanziiere und es zurückgebe, wird es als Referenz oder als Wert zurückgegeben. IE - sollte ich über die Leistung besorgt sein, wenn ich etwas wie dieses schreibe:

Public Function ret_obj_func() As big_object
    Dim ret_obj As New big_obj(<lots of stuff>)
    Return ret_obj
End Function

Wenn ich diese Funktion von einem anderen Ort aus aufrufe, wird das Objekt in ret_obj instanziiert und dann eine tiefe Kopie erstellt, um eine Kopie an den Aufrufer zurückzugeben, oder wird nur eine Referenz zurückgegeben?

8voto

hoodaticus Punkte 3621

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:

  1. Datum
  2. Char
  3. U/Int(16/32/64)
  4. Dezimal
  5. Einzel und Doppel
  6. Boolesche
  7. Strukturen
  8. 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.

7voto

Jon Skeet Punkte 1325502

Es wird lediglich eine Referenz zurückgegeben (unter der Annahme, dass big_obj ist eine Klasse). Ich würde den Begriff "by reference" hier nicht verwenden, da er bei der Übergabe von Parametern eine ganz andere Bedeutung hat - aber unter der Annahme big_obj ist eine Klasse - ein Referenztyp - der Wert von ret_obj ist ein Verweis, und dieser Verweis wird zurückgegeben.

Ich habe keine Artikel zu diesem Thema aus der VB-Perspektive, aber wenn Sie sich gerne mit C# beschäftigen, finden Sie vielleicht diese Artikel nützlich:

0voto

Brian Gideon Punkte 46450

VB.NET verfügt nicht über die Möglichkeit, per Referenz zurückzukehren. Genauso wenig wie C#, aber es wurde vorgeschlagen . Was Sie tatsächlich zurückbekommen, ist nur ein Verweis auf das Objekt. Um dies genau zu definieren, heißt es also gibt eine Referenz zurück zum Objekt. Es tut nicht Rückgabe per Verweis wie das, was man mit dem ByRef Stichwort.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X