Hi,
Please let me know if I am interpreting this correctly. I've done a
little testing of the difference between passing parameters byVal and
byRef, and the results were slightly non-intuitive, as I expected. I
haven't seen this behavior explained precisely in the .net world yet,
so I wanted to check and make sure I've got it right.
I apologize that this is a bit long. I've tried to keep it concise.
There are code fragments here, but you should be able to scan through
without actually cutting, pasting and running it.
I've got a class, DataHider, with one private string field (i.e.,
private, non-shared module-level variable of type string). DataHider
also has simple public getter and setter methods for the field, which
do nothing other than retrieve or set the values. It's simple because
it's just for testing.
Then I've got a module with two nearly-identical routines, that only
differ by how the parameters are passed to it:
Public Sub callObjectMethodPassedByVal(ByVal myObj As
DataHider)
myObj.setMyData("abcdef")
End Sub
Public Sub callObjectMethodPassedByRef(ByRef myObj As
DataHider)
myObj.setMyData("abcdef")
End Sub
The counterintuitive thing (at least to me) is that *both* of these
routines succeed in changing the data value in myObj, as you can test
with this code fragment if you like:
Private Sub Button2_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles Button2.Click
Dim hider As New DataHider
Debug.WriteLine("**** Test 2 ****")
hider.setMyData("fred")
Debug.WriteLine("Initial data is: " & hider.getMyData)
objectByVal(hider)
Debug.WriteLine( _
"Data after changing in a sub called byVal is: " _
& hider.getMyData)
objectByRef(hider)
Debug.WriteLine( _
"Data after changing in a sub called byRef is: " _
& hider.getMyData)
End Sub
This routine ends up printing the following in the output window:
**** Test 2 ****
Initial data is: fred
Data after changing in a sub called byVal is: abcdef
Data after changing in a sub called byRef is: abcdef
*****************
I would have thought that an object passed in byVal couldn't be
changed. Now it seems that it all depends on what you mean by "change"
(and perhaps, what "is" is...) It seems that thinking of byVal as
meaning that the called routine works on a "copy" of the passed in
object is at best misleading.
My explanation (please tell me if this is accurate) is that
When you pass an object by value, you are essentially passing its
*address*, and the address is the part that can't be changed. How is
this different than passing byRef? I think that the difference only
shows up when you try to reassign the passed in parameter to another
object (i.e, issue a "myObj = whatever" statement). As long as you
don't do that, it appears to me that byRef and byVal function more or
less identically.
****************
More tests:
reassign the object before changing the data value:
Public Sub objectByVal3(ByVal myObj As DataHider)
myObj = New DataHider 'This is new
myObj.setMyData("abcdef")
End Sub
Public Sub objectByRef3(ByRef myObj As DataHider)
myObj = New DataHider 'This is new
myObj.setMyData("abcdef")
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button3.Click
Dim hider As New DataHider
Debug.WriteLine("**** Test 3 ****")
hider.setMyData("fred")
Debug.WriteLine("Initial data is: " & hider.getMyData)
objectByVal3(hider)
Debug.WriteLine( _
"Data after changing in a sub called byVal is: " _
& hider.getMyData)
objectByRef3(hider)
Debug.WriteLine( _
"Data after changing in a sub called byRef is: " _
& hider.getMyData)
End Sub
**** Test 3 ****
Initial data is: fred
Data after changing in a sub called byVal is: fred
Data after changing in a sub called byRef is: abcdef
I think this evidence tends to confirm my theory.
************************************************** ****
One more tiny, but fascinating test:
In a single module, declare
private m_hider as DataHider
and the following two routines:
Public Sub objectByVal4(ByVal myObj As DataHider)
Debug.WriteLine(myObj Is m_hider)
End Sub
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button4.Click
Debug.WriteLine("**** Test 4 ****")
m_hider = New DataHider 'm_hider has to be declared at module
'level
objectByVal4(m_hider)
End Sub
When you call objectByVal4 from the Click event as above, it prints
"True". I find this to be massively counterintuitive, unless you think
of byVal as a copy of the address of the object. In that view, it makes
perfect sense that if you add "myObj = New DataHider" before the
debug.writeline, you will then get a False printout in the output
window. That is, in fact, what occurs.
I'd appreciate any corrections or clarifications to this
conceptualization of the difference between the two passing methods.
Thanks,
Warren 4 2433
Warren,
ByVal & ByRef Parameters are independent of Reference & Value Types. All
parameters in VB.NET by default are passed ByVal, you should only pass a
parameter ByRef when you have to, which is when you need to modify the
callers variable.
A Reference Type is an object that exists on the heap. If I have a variable
that is a reference type and assign the variable to another variable. Both
variables will be pointing to the same object on the heap.
Dim x As Person
x = New Person()
Dim y As Person
y = x
Both x & y are the exact same Person object on the heap.
A Value Type does not live on the Heap. If I have a value type variable and
I assign it to another variable, a copy of the value is made.
Dim x As Integer
x = 100
Dim y As Integer
y = x
Although both x & y have the value 100, they are physically different values
as a copy was made.
Now when you pass a variable to a ByVal parameter a copy of the variable is
made. So for a Reference Type a copy of the reference is made, which means
there is still only one object on the heap & two references to that object.
For a Value Type a copy of the value is made.
When you pass a variable to a ByRef parameter a reference to that variable
is made. So for a Reference Type you have a reference to a reference to the
object, for a Value Type you have a reference to the value.
Remember ByVal & ByRef are how parameters are passed. Reference & Value
Types are how quantities are stored.
The following site also does a good job of explaining Reference & Value
types & ByRef & ByVal parameters. http://www.yoda.arachsys.com/csharp/parameters.html
Hope this helps
Jay
"Warren Sirota" <ws*****@wsdesigns.com> wrote in message
news:ee**************@TK2MSFTNGP10.phx.gbl... Hi,
Please let me know if I am interpreting this correctly. I've done a little testing of the difference between passing parameters byVal and byRef, and the results were slightly non-intuitive, as I expected. I haven't seen this behavior explained precisely in the .net world yet, so I wanted to check and make sure I've got it right.
I apologize that this is a bit long. I've tried to keep it concise. There are code fragments here, but you should be able to scan through without actually cutting, pasting and running it.
I've got a class, DataHider, with one private string field (i.e., private, non-shared module-level variable of type string). DataHider also has simple public getter and setter methods for the field, which do nothing other than retrieve or set the values. It's simple because it's just for testing.
Then I've got a module with two nearly-identical routines, that only differ by how the parameters are passed to it:
Public Sub callObjectMethodPassedByVal(ByVal myObj As DataHider) myObj.setMyData("abcdef") End Sub
Public Sub callObjectMethodPassedByRef(ByRef myObj As DataHider) myObj.setMyData("abcdef") End Sub
The counterintuitive thing (at least to me) is that *both* of these routines succeed in changing the data value in myObj, as you can test with this code fragment if you like:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim hider As New DataHider Debug.WriteLine("**** Test 2 ****") hider.setMyData("fred") Debug.WriteLine("Initial data is: " & hider.getMyData) objectByVal(hider) Debug.WriteLine( _ "Data after changing in a sub called byVal is: " _ & hider.getMyData) objectByRef(hider) Debug.WriteLine( _ "Data after changing in a sub called byRef is: " _ & hider.getMyData)
End Sub
This routine ends up printing the following in the output window: **** Test 2 **** Initial data is: fred Data after changing in a sub called byVal is: abcdef Data after changing in a sub called byRef is: abcdef
***************** I would have thought that an object passed in byVal couldn't be changed. Now it seems that it all depends on what you mean by "change" (and perhaps, what "is" is...) It seems that thinking of byVal as meaning that the called routine works on a "copy" of the passed in object is at best misleading.
My explanation (please tell me if this is accurate) is that When you pass an object by value, you are essentially passing its *address*, and the address is the part that can't be changed. How is this different than passing byRef? I think that the difference only shows up when you try to reassign the passed in parameter to another object (i.e, issue a "myObj = whatever" statement). As long as you don't do that, it appears to me that byRef and byVal function more or less identically.
**************** More tests:
reassign the object before changing the data value:
Public Sub objectByVal3(ByVal myObj As DataHider) myObj = New DataHider 'This is new myObj.setMyData("abcdef") End Sub Public Sub objectByRef3(ByRef myObj As DataHider) myObj = New DataHider 'This is new myObj.setMyData("abcdef") End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click Dim hider As New DataHider Debug.WriteLine("**** Test 3 ****") hider.setMyData("fred") Debug.WriteLine("Initial data is: " & hider.getMyData) objectByVal3(hider) Debug.WriteLine( _ "Data after changing in a sub called byVal is: " _ & hider.getMyData) objectByRef3(hider) Debug.WriteLine( _ "Data after changing in a sub called byRef is: " _ & hider.getMyData) End Sub
**** Test 3 **** Initial data is: fred Data after changing in a sub called byVal is: fred Data after changing in a sub called byRef is: abcdef
I think this evidence tends to confirm my theory.
************************************************** **** One more tiny, but fascinating test:
In a single module, declare private m_hider as DataHider
and the following two routines:
Public Sub objectByVal4(ByVal myObj As DataHider) Debug.WriteLine(myObj Is m_hider) End Sub
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click Debug.WriteLine("**** Test 4 ****") m_hider = New DataHider 'm_hider has to be declared at module 'level objectByVal4(m_hider) End Sub
When you call objectByVal4 from the Click event as above, it prints "True". I find this to be massively counterintuitive, unless you think of byVal as a copy of the address of the object. In that view, it makes perfect sense that if you add "myObj = New DataHider" before the debug.writeline, you will then get a False printout in the output window. That is, in fact, what occurs.
I'd appreciate any corrections or clarifications to this conceptualization of the difference between the two passing methods.
Thanks, Warren
Warren,
ByVal & ByRef Parameters are independent of Reference & Value Types. All
parameters in VB.NET by default are passed ByVal, you should only pass a
parameter ByRef when you have to, which is when you need to modify the
callers variable.
A Reference Type is an object that exists on the heap. If I have a variable
that is a reference type and assign the variable to another variable. Both
variables will be pointing to the same object on the heap.
Dim x As Person
x = New Person()
Dim y As Person
y = x
Both x & y are the exact same Person object on the heap.
A Value Type does not live on the Heap. If I have a value type variable and
I assign it to another variable, a copy of the value is made.
Dim x As Integer
x = 100
Dim y As Integer
y = x
Although both x & y have the value 100, they are physically different values
as a copy was made.
Now when you pass a variable to a ByVal parameter a copy of the variable is
made. So for a Reference Type a copy of the reference is made, which means
there is still only one object on the heap & two references to that object.
For a Value Type a copy of the value is made.
When you pass a variable to a ByRef parameter a reference to that variable
is made. So for a Reference Type you have a reference to a reference to the
object, for a Value Type you have a reference to the value.
Remember ByVal & ByRef are how parameters are passed. Reference & Value
Types are how quantities are stored.
The following site also does a good job of explaining Reference & Value
types & ByRef & ByVal parameters. http://www.yoda.arachsys.com/csharp/parameters.html
Hope this helps
Jay
"Warren Sirota" <ws*****@wsdesigns.com> wrote in message
news:ee**************@TK2MSFTNGP10.phx.gbl... Hi,
Please let me know if I am interpreting this correctly. I've done a little testing of the difference between passing parameters byVal and byRef, and the results were slightly non-intuitive, as I expected. I haven't seen this behavior explained precisely in the .net world yet, so I wanted to check and make sure I've got it right.
I apologize that this is a bit long. I've tried to keep it concise. There are code fragments here, but you should be able to scan through without actually cutting, pasting and running it.
I've got a class, DataHider, with one private string field (i.e., private, non-shared module-level variable of type string). DataHider also has simple public getter and setter methods for the field, which do nothing other than retrieve or set the values. It's simple because it's just for testing.
Then I've got a module with two nearly-identical routines, that only differ by how the parameters are passed to it:
Public Sub callObjectMethodPassedByVal(ByVal myObj As DataHider) myObj.setMyData("abcdef") End Sub
Public Sub callObjectMethodPassedByRef(ByRef myObj As DataHider) myObj.setMyData("abcdef") End Sub
The counterintuitive thing (at least to me) is that *both* of these routines succeed in changing the data value in myObj, as you can test with this code fragment if you like:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim hider As New DataHider Debug.WriteLine("**** Test 2 ****") hider.setMyData("fred") Debug.WriteLine("Initial data is: " & hider.getMyData) objectByVal(hider) Debug.WriteLine( _ "Data after changing in a sub called byVal is: " _ & hider.getMyData) objectByRef(hider) Debug.WriteLine( _ "Data after changing in a sub called byRef is: " _ & hider.getMyData)
End Sub
This routine ends up printing the following in the output window: **** Test 2 **** Initial data is: fred Data after changing in a sub called byVal is: abcdef Data after changing in a sub called byRef is: abcdef
***************** I would have thought that an object passed in byVal couldn't be changed. Now it seems that it all depends on what you mean by "change" (and perhaps, what "is" is...) It seems that thinking of byVal as meaning that the called routine works on a "copy" of the passed in object is at best misleading.
My explanation (please tell me if this is accurate) is that When you pass an object by value, you are essentially passing its *address*, and the address is the part that can't be changed. How is this different than passing byRef? I think that the difference only shows up when you try to reassign the passed in parameter to another object (i.e, issue a "myObj = whatever" statement). As long as you don't do that, it appears to me that byRef and byVal function more or less identically.
**************** More tests:
reassign the object before changing the data value:
Public Sub objectByVal3(ByVal myObj As DataHider) myObj = New DataHider 'This is new myObj.setMyData("abcdef") End Sub Public Sub objectByRef3(ByRef myObj As DataHider) myObj = New DataHider 'This is new myObj.setMyData("abcdef") End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click Dim hider As New DataHider Debug.WriteLine("**** Test 3 ****") hider.setMyData("fred") Debug.WriteLine("Initial data is: " & hider.getMyData) objectByVal3(hider) Debug.WriteLine( _ "Data after changing in a sub called byVal is: " _ & hider.getMyData) objectByRef3(hider) Debug.WriteLine( _ "Data after changing in a sub called byRef is: " _ & hider.getMyData) End Sub
**** Test 3 **** Initial data is: fred Data after changing in a sub called byVal is: fred Data after changing in a sub called byRef is: abcdef
I think this evidence tends to confirm my theory.
************************************************** **** One more tiny, but fascinating test:
In a single module, declare private m_hider as DataHider
and the following two routines:
Public Sub objectByVal4(ByVal myObj As DataHider) Debug.WriteLine(myObj Is m_hider) End Sub
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click Debug.WriteLine("**** Test 4 ****") m_hider = New DataHider 'm_hider has to be declared at module 'level objectByVal4(m_hider) End Sub
When you call objectByVal4 from the Click event as above, it prints "True". I find this to be massively counterintuitive, unless you think of byVal as a copy of the address of the object. In that view, it makes perfect sense that if you add "myObj = New DataHider" before the debug.writeline, you will then get a False printout in the output window. That is, in fact, what occurs.
I'd appreciate any corrections or clarifications to this conceptualization of the difference between the two passing methods.
Thanks, Warren
Jay:
That's a terrific reference. Thanks so much.
Warren
Jay B. Harlow [MVP - Outlook] wrote: The following site also does a good job of explaining Reference & Value types & ByRef & ByVal parameters.
http://www.yoda.arachsys.com/csharp/parameters.html
Hope this helps Jay
Jay:
That's a terrific reference. Thanks so much.
Warren
Jay B. Harlow [MVP - Outlook] wrote: The following site also does a good job of explaining Reference & Value types & ByRef & ByVal parameters.
http://www.yoda.arachsys.com/csharp/parameters.html
Hope this helps Jay
This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Mike |
last post by:
Hi All,
I have been struggling with this for weeks now and I just can't get my
head around it. I am trying to convert this procedure to VB.NET. In
particular I am having problems with the...
|
by: Sandy |
last post by:
Hello!
Help!!!!
I have ten zillion books that attempt to describe the
difference between ByVal and ByRef and none of them are
clear to me. I have gathered that ByVal makes a copy and
ByRef...
|
by: john |
last post by:
Here is the short story of what i'm trying to do. I have a 4 sided case
labeling printer setting out on one of our production lines. Now then i have
a vb.net application that sends data to this...
|
by: Hei |
last post by:
Hi,
i know the difference of ByRef and ByVal, in case if use byref or byval
don't affect the result which one should prefer? (less memory use, better
performance ....issue)
thx
|
by: John Regan |
last post by:
Hello All
I am trying to find the owner of a file or folder on our network (Windows
2000 Server) using VB.Net and/or API. so I can search for Folders that don't
follow our company's specified...
|
by: Robin Tucker |
last post by:
Although I've been working on this project for 8 months now, I'm still not
sure of the difference between ByVal and ByRef. As most objects in VB are
reference types, passing ByVal I've discovered...
|
by: Warren Sirota |
last post by:
Hi,
Please let me know if I am interpreting this correctly. I've done a
little testing of the difference between passing parameters byVal and
byRef, and the results were slightly non-intuitive,...
|
by: Terrance |
last post by:
Hello, I was wondering if someone can help me understand something. Below is
some code that I got from the MS website that is suppose to authenticate for
the username and password on the local...
|
by: Vayse |
last post by:
I found this code on the MSDN site, from a post thats about a year old.
It does seem to work. However, I'm confused in how to use the impersonated
user.
I'd like to use impersonatedUser to run...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
| |