Long ago I wrote about byref & byval
Apparently this wasnt widely read not even by some long standing members of the community as I still see completely wrong explanations of bevel & byref persist.
First you have to understand that there are two types of VARIABLES.
VALUE types and REFERENCE types.
With a VALUE type the compiler sees there is space in memory set aside when your program runs to hold a value – a number a floating point value etc. The thing IN that spot IS the actual data.
With a REFERENCE type whats in that spot isnt the data directly – it s the address of the data.
Normally when you pass a value you pass it BYVAL
This is the default
So what exactly does this mean ?
I literally means that the value that is held by whatever type of variable is passed in can’t be altered.
If you pass in an integer, IN the method you can change it however you want, but those changes WILL NOT be preserved in the calling code.
Something like
Sub Opening
dim I as integer = 100
system.debuglog str(i) // prints 100
foo(i)
system.debuglog str(i) // prints 100
end sub
sub foo ( I as integer )
I = 500
system.debuglog "in foo " + str(i) // prints in foo 500
end sub
Would print 100 and 500 as indicated. The value would not be preserved from the call to foo. So when we return the next time I is printed in the caller it prints 100.
This is the easy case for a VALUE type.
If we switch to a REFERENCE type its EXACTLY THE SAME ! The trick is “the value” that is preserved is the pointer, or reference, that is preserved. NOT THE data referred to. Let me illustrate
Sub Opening
Dim d As New date
System.debuglog d.SQLDateTime
foo(d)
System.debuglog d.SQLDateTime
End Sub
sub foo ( d as date )
d = New date(d.year - 2, d.month - 4, d.day - 6, _
d.hour - 8, d.minute - 10)
System.debuglog "in foo = " + d.SQLDateTime
end sub
Note that if you run this you will see that d in the main calling routine before & after the call prints the SAME date. This despite the fact that in the called routine, foo, we altered the date that d referred to.
What this shows is that what is being passed by VALUE is the REFERENCE (pointer or address)
And again IN the routine we called we can do whatever we want to change what the REFERENCE is by creating a new one and that change wont stick when we leave.
- there IS a thing that many people referen to as “byref” that ISNT
SEE THE END OF THIS ARTICLE
No wit we switch to using BYREF to make it so “changes to the value held” are preserved we get
Sub Opening
dim I as integer = 100
system.debuglog str(i) // prints 100
foo(i)
system.debuglog str(i) // prints 500 !!!!!!!!!!!!
end sub
sub foo ( byref I as integer )
I = 500
system.debuglog "in foo " + str(i) // prints in foo 500
end sub
The change to the value held IS preserved !
BYREF allows us to alter what the variable held
And for BYREF with a reference type its much the same
Sub Opening
Dim d As New date
System.debuglog d.SQLDateTime
foo(d)
System.debuglog d.SQLDateTime // prints THE SAME as from foo !!!!
End Sub
sub foo ( byref d as date )
d = New date(d.year - 2, d.month - 4, d.day - 6, _
d.hour - 8, d.minute - 10)
System.debuglog "in foo = " + d.SQLDateTime
end sub
BYREF lets you change what the VALUE of the passed in variable is.
But, it depends on what kind of value is passed in to see what the effects are
SOME people incorrectly refer to the following as “byref”
Sub Opening
Dim d As New date
System.debuglog d.SQLDateTime
foo(d)
System.debuglog d.SQLDateTime // prints THE SAME as from foo !!!!
End Sub
sub foo ( d as date )
d.hour = d.hour - 12
System.debuglog "in foo = " + d.SQLDateTime
end sub
Bu this is NOT “byref”
We haven’t change the REFERENCE ( the actual instance) being referred to
We HAVE altered one of the properties of the item passed in – that happens to be a reference type
I hope this clears up the confusion