Differance between ByVal and BeRef when handling objects

G

Guest

Hi
What I have learned is that a variable is just a reference when dealing with Objects.
Are you supposed to use ByVal or ByRef in functions? They produce the same result or have I missed something?
Regards
/Niklas

Public Class Main
Shared Sub Main()
Dim testPropObj As New MyPropertObject
testPropObj.MyInt = 1
Console.WriteLine("Org: testPropObj.MyInt = " & testPropObj.MyInt)
ChangeObjectByVal(testPropObj)
Console.WriteLine("ByVal: testPropObj = " & testPropObj.MyInt)
ChangeObjectByRef(testPropObj)
Console.WriteLine("ByRef: testPropObj = " & testPropObj.MyInt)
Console.WriteLine("Press Enter to exit...")
Console.ReadLine()
End Sub

Public Shared Sub ChangeObjectByVal(ByVal myObject As MyPropertObject)
myObject.MyInt = 5
End Sub

Public Shared Sub ChangeObjectByRef(ByRef myObject As MyPropertObject)
myObject.MyInt = 6
End Sub
End Class

Public Class MyPropertObject
Public MyInt As Integer
End Class
 
S

Shiva

Hi,

The output you are getting is indeed correct.

The way ByVal & ByRef differs in case of reference type is like this: When a
ref type variable is passed ByVal, a copy of the reference var is passed
(ie, two vars for the same object). So, if you assign a new instance of the
class inside the called method to the ByVal var, the original remains
intact. On the other hand, ByRef passes the reference var as is. Any new
reference assignment in the called method will change what the original var
was pointing at.

I have modified the code below to show the difference. Run it and check the
results.

Hi
What I have learned is that a variable is just a reference when dealing with
Objects.
Are you supposed to use ByVal or ByRef in functions? They produce the same
result or have I missed something?
Regards
/Niklas

Public Class Main
Shared Sub Main()
Dim testPropObj As New MyPropertObject
testPropObj.MyInt = 1
Console.WriteLine("Org: testPropObj.MyInt = " & testPropObj.MyInt)
ChangeObjectByVal(testPropObj)
Console.WriteLine("ByVal: testPropObj = " & testPropObj.MyInt)
ChangeObjectByRef(testPropObj)
Console.WriteLine("ByRef: testPropObj = " & testPropObj.MyInt)
Console.WriteLine("Press Enter to exit...")
Console.ReadLine()
End Sub

Public Shared Sub ChangeObjectByVal(ByVal myObject As MyPropertObject)
myObject = New MyPropertObject
myObject.MyInt = 5
End Sub

Public Shared Sub ChangeObjectByRef(ByRef myObject As MyPropertObject)
myObject = New MyPropertObject
myObject.MyInt = 6
End Sub
End Class

Public Class MyPropertObject
Public MyInt As Integer
End Class
 
C

Cor Ligthert

Hi Niklas,

You can almost forever use ByVal
It is with a value the value itself and with an existing object the value of
the reference of the object.

Above I write already when it cannot be used ByVal, that is when the object
is declared however not created yet. Than you have to do it for an object
ByRef.

I hope this helps?

Cor
 
G

Guest

Thank you. That means that I have to redesign my application because the Set part of Property do not allow ByRef only ByVal...maybe I use a field.
Regards
/Niklas
 
J

Jay B. Harlow [MVP - Outlook]

Niklas,
Why would you need to redesign your app?

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. Property Set routines should not be modifying the caller's
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.

Hope this helps
Jay


Niklas said:
Thank you. That means that I have to redesign my application because the
Set part of Property do not allow ByRef only ByVal...maybe I use a field.
 
D

David Anton

I used to use this as an interview question...

When you're passing an object to a method - you're passing a variable
which points to the object. Both ByVal or ByRef pass a variable
which points to the object since a copy of an address is still the
valid address, so the object modifications persists upon leaving the
method. All ByVal does in this case is prevent you from changing the
variable pointing to the object to point to another object upon
leaving the method.
 
G

Guest

Are you sure that when you pass an array ByVal that a copy is made of the entire array?
 
G

Guest

Thanks all of you. I did some test on my application and ByVal did the job.
Regards
/Niklas
 
S

Shiva

Hi,

I meant a 'copy of the reference' (address) is made not what the ref points
to.

Are you sure that when you pass an array ByVal that a copy is made of the
entire array?
 
H

- HAL9000

Yea I've wondered the same thing. Duplicating a large array sounds
prohibitively expensive. Maybe the byref and byvalue or just
specifying permission to write ????

Forrest
 
H

- HAL9000

Should one be allowed to write to an array that is passed by value?

If you are then that doesn't sound consistent with passing an integer
byvalue. Doesn't passing byvalue imply that you absolutely don't want
the original integer to be modified?

Forrest
 
J

Jay B. Harlow [MVP - Outlook]

Forrest,
See my earlier response. You are confusing passing parameters ByVal & ByRef
with Value Types & Reference types.

Hope this helps
Jay
 
D

David Anton

- HAL9000wrote:
Should one be allowed to write to an array that is passed by value?
If you are then that doesn't sound consistent with passing an integer
byvalue. Doesn't passing byvalue imply that you absolutely don't want
the original integer to be modified?

Forrest

On 22 Jul 2004 17:03:34 -0500,
(e-mail address removed)-spam.invalid (David Anton)
wrote:

I used to use this as an interview question...

When you're passing an object to a method - you're passing a variable
which points to the object. Both ByVal or ByRef pass a variable
which points to the object since a copy of an address is still the
valid address, so the object modifications persists upon leaving the
method. All ByVal does in this case is prevent you from changing the
variable pointing to the object to point to another object upon
leaving the method.[/quote:03c44a920a]

By all means. All that was conveyed & forced in the method
signature is that you can't point the original array at some other
array.

There's no nice way I know of to prevent a method from mucking about
with an object. Maybe there should be...
There is a work-around if you need to pass an object and absolutely
don't want the method to change anything within it - pass a copy of
the object created for the sole purpose of passing the object's
information to the method.
 
H

- HAL9000

Exactly, that is what the language does with an integer (copy it and
place on stack) so it would be consistent for the language to do the
same with an array/object.

I guess if we all understand what is going on then the language can
have quirks...

Forrest



On 23 Jul 2004 23:02:50 -0500,
(e-mail address removed)-spam.invalid (David Anton)
wrote:
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top