473,573 Members | 3,281 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Please help me clarify these byVal vs. byRef subtleties

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 callObjectMetho dPassedByVal(By Val myObj As
DataHider)
myObj.setMyData ("abcdef")
End Sub

Public Sub callObjectMetho dPassedByRef(By Ref myObj As
DataHider)
myObj.setMyData ("abcdef")
End Sub

The counterintuitiv e 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(B yVal sender As System.Object,
ByVal e As System.EventArg s) Handles Button2.Click
Dim hider As New DataHider
Debug.WriteLine ("**** Test 2 ****")
hider.setMyData ("fred")
Debug.WriteLine ("Initial data is: " & hider.getMyData )
objectByVal(hid er)
Debug.WriteLine ( _
"Data after changing in a sub called byVal is: " _
& hider.getMyData )
objectByRef(hid er)
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(By Val myObj As DataHider)
myObj = New DataHider 'This is new
myObj.setMyData ("abcdef")
End Sub
Public Sub objectByRef3(By Ref myObj As DataHider)
myObj = New DataHider 'This is new
myObj.setMyData ("abcdef")
End Sub

Private Sub Button3_Click(B yVal sender As System.Object, ByVal e As
System.EventArg s) Handles Button3.Click
Dim hider As New DataHider
Debug.WriteLine ("**** Test 3 ****")
hider.setMyData ("fred")
Debug.WriteLine ("Initial data is: " & hider.getMyData )
objectByVal3(hi der)
Debug.WriteLine ( _
"Data after changing in a sub called byVal is: " _
& hider.getMyData )
objectByRef3(hi der)
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(By Val myObj As DataHider)
Debug.WriteLine (myObj Is m_hider)
End Sub
Private Sub Button4_Click(B yVal sender As System.Object, ByVal e As
System.EventArg s) 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 counterintuitiv e, 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
conceptualizati on of the difference between the two passing methods.

Thanks,
Warren
Nov 21 '05 #1
4 2457
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*****@wsdesi gns.com> wrote in message
news:ee******** ******@TK2MSFTN GP10.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 callObjectMetho dPassedByVal(By Val myObj As
DataHider)
myObj.setMyData ("abcdef")
End Sub

Public Sub callObjectMetho dPassedByRef(By Ref myObj As
DataHider)
myObj.setMyData ("abcdef")
End Sub

The counterintuitiv e 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(B yVal sender As System.Object,
ByVal e As System.EventArg s) Handles Button2.Click
Dim hider As New DataHider
Debug.WriteLine ("**** Test 2 ****")
hider.setMyData ("fred")
Debug.WriteLine ("Initial data is: " & hider.getMyData )
objectByVal(hid er)
Debug.WriteLine ( _
"Data after changing in a sub called byVal is: " _
& hider.getMyData )
objectByRef(hid er)
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(By Val myObj As DataHider)
myObj = New DataHider 'This is new
myObj.setMyData ("abcdef")
End Sub
Public Sub objectByRef3(By Ref myObj As DataHider)
myObj = New DataHider 'This is new
myObj.setMyData ("abcdef")
End Sub

Private Sub Button3_Click(B yVal sender As System.Object, ByVal e As
System.EventArg s) Handles Button3.Click
Dim hider As New DataHider
Debug.WriteLine ("**** Test 3 ****")
hider.setMyData ("fred")
Debug.WriteLine ("Initial data is: " & hider.getMyData )
objectByVal3(hi der)
Debug.WriteLine ( _
"Data after changing in a sub called byVal is: " _
& hider.getMyData )
objectByRef3(hi der)
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(By Val myObj As DataHider)
Debug.WriteLine (myObj Is m_hider)
End Sub
Private Sub Button4_Click(B yVal sender As System.Object, ByVal e As
System.EventArg s) 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 counterintuitiv e, 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
conceptualizati on of the difference between the two passing methods.

Thanks,
Warren

Nov 21 '05 #2
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*****@wsdesi gns.com> wrote in message
news:ee******** ******@TK2MSFTN GP10.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 callObjectMetho dPassedByVal(By Val myObj As
DataHider)
myObj.setMyData ("abcdef")
End Sub

Public Sub callObjectMetho dPassedByRef(By Ref myObj As
DataHider)
myObj.setMyData ("abcdef")
End Sub

The counterintuitiv e 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(B yVal sender As System.Object,
ByVal e As System.EventArg s) Handles Button2.Click
Dim hider As New DataHider
Debug.WriteLine ("**** Test 2 ****")
hider.setMyData ("fred")
Debug.WriteLine ("Initial data is: " & hider.getMyData )
objectByVal(hid er)
Debug.WriteLine ( _
"Data after changing in a sub called byVal is: " _
& hider.getMyData )
objectByRef(hid er)
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(By Val myObj As DataHider)
myObj = New DataHider 'This is new
myObj.setMyData ("abcdef")
End Sub
Public Sub objectByRef3(By Ref myObj As DataHider)
myObj = New DataHider 'This is new
myObj.setMyData ("abcdef")
End Sub

Private Sub Button3_Click(B yVal sender As System.Object, ByVal e As
System.EventArg s) Handles Button3.Click
Dim hider As New DataHider
Debug.WriteLine ("**** Test 3 ****")
hider.setMyData ("fred")
Debug.WriteLine ("Initial data is: " & hider.getMyData )
objectByVal3(hi der)
Debug.WriteLine ( _
"Data after changing in a sub called byVal is: " _
& hider.getMyData )
objectByRef3(hi der)
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(By Val myObj As DataHider)
Debug.WriteLine (myObj Is m_hider)
End Sub
Private Sub Button4_Click(B yVal sender As System.Object, ByVal e As
System.EventArg s) 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 counterintuitiv e, 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
conceptualizati on of the difference between the two passing methods.

Thanks,
Warren

Nov 21 '05 #3
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

Nov 21 '05 #4
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

Nov 21 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
2054
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 CopyMemory and ZeroMemory calls. I have been messing around with the Marshal class but just can't seem to get it to work. Can anybody help me with this...
8
383
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 points to something and changes it. The default for simple data types is ByVal and for objects, it's ByRef. Am I correct so far? If so, I still...
5
3339
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 printer using a RawPrinterHelper class that i found I believe in the msdn. the class works wonderfully when I send stright text data (in the...
7
5493
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
2
5031
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 folder structure and naming conventions and then send a Net send message to those users telling them to rectify. The information I want to get is when...
14
2497
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 allows me to store a reference to the object I passed by val, to change that object and for the change to be reflected in the callers copy of the...
0
300
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, 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...
1
1302
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 machine. I tested this code in VB.net 2003 in a WINDOW FORM class and it seems to work fine. However, when I test it in VB.net 2005 Express Edition it...
0
895
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 some SQL commands. Any idea how I would do this? Thanks Vayse '************************************************************************* Imports...
0
7741
marktang
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7977
Oralloy
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8163
jinu1996
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
5550
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5252
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3692
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3681
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1254
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
984
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.