This should be a fairly common question, but I haven't found a straightforward answer anywhere.
If I instantiate an object within a function in VB.NET and return it, does it return it by reference or by value. IE - should I be worried about performance if I write something like this:
Public Function ret_obj_func() As big_object
Dim ret_obj As New big_obj(<lots of stuff>)
Return ret_obj
End Function
If I call this function from somewhere else, will it instantiate the object in the ret_obj and then create a deep copy to pass back a copy to the caller, Or will it just pass back a reference?
There are two dichotomous issues here with similar vocabulary involved: value versus reference types, and passing variables by value versus by reference.
The first issue is value versus reference types. Value types are passed around through copying - usually. The value types are:
All but the above-listed types are reference types. When an object gets passed around, what is actually being passed is its memory address, which is often thought of as an int on 32 bit platforms and a long on 64 bit platforms.
The second issue is passing a variable by value versus reference.
A variable is a slot at a certain position in memory that can hold stuff. For value types, it holds the actual value. For reference types, it holds the memory address of the object on the heap (or is Nothing).
By Value
When you pass a variable by value, whatever is at that variable's memory location is what gets copied. For value types, that means the value itself is copied. For reference types, what gets copied is the memory address of the object refered to by the variable.
By Reference
Remember that a variable is just a slot in memory for holding stuff. When you pass a variable by reference, you are passing the address of that slot (as opposed to the data in that slot).
If that variable is a value type, that slot holds the value itself, so the thing being passed is a pointer to the value.
If that variable is a reference type, the slot is holding a pointer to the object's location in memory, so the thing being passed is a pointer to your variable (just like with value types), which itself contains another pointer (not like value types) which leads to the memory location that holds the object referred to by the variable.
This allows a function to modify a variable in another function, like this:
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
Let's compare to the situation where you pass by value:
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
In the above example, Boolean is a value type. If it were an object, IReceiveByReference would have the power to point myVariable to an entirely new object, because it received the address of myVariable - not the address of the object to which myVariable points. By contrast, IReceiveByValue was only passed the contents of myVariable, so it cannot change myVariable to point to a new object. It could still change the object by setting its fields and properties and calling its methods, though.
Return By-Reference?
Although functions can pass variables by reference, they cannot return them that way. When a function returns, its local variables do not exist anymore (or are pending cleanup if they are heap-allocated). Functions therefore always return by value; because the local variables don't have valid memory addresses anymore, there aren't any variable references to return.
Putting it all together, when you return an object from a function, the only thing that is copied is the address of the object. When you return a value type from a function, the value itself is copied.
This means reference types are essentially value types, wherein the value is the memory address of an object on the heap, (or Nothing).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With