This is a common question asked on nearly every forum I have seen, and the answer is simple:
Rule 1: When passing an Object (Reference Type) ByVal, a copy of the Object is passed.
Rule 2: A variable (Value Type) passed ByVal is not affected by the code inside the method, while a variable passed ByRef is.
To demonstrate, build and run this simple Console Application:
Public Module1
Public Sub DoSomething(ByVal x As Integer, ByRef As Double)
x += 5
y += 5
Console.WriteLine("Inside Method Call:")
Console.WriteLine("num= {0}", x.ToString)
Console.WriteLine("anum = {0}", y.ToString)
End Sub
Sub Main()
Dim num As Integer = 5
Dim anum As Double = 20.5
Console.WriteLine("Before Method Call:")
Console.WriteLine("num = {0}", num.ToString)
Console.WriteLine("anum = {0}", anum.ToString)
DoSomething(num, anum)
Console.WriteLine("After Method Call:")
Console.WriteLine("num = {0}", num.ToString)
Console.WriteLine("anum = {0}", anum.ToString)
Console.Read()
End Sub
End Module
Result:
Before Method Call:
num = 5
anum = 20.5
Inside Method Call:
num = 10
anum = 25.5
After Method Call:
num = 5
anum = 25.5
Note that in the code, we set two variables and initialize them:
Dim num as Integer = 5,
Dim anum as Double = 20.5
After displaying the initialized values, we call the method DoSomething(), supplying our variables as parameters. num is passed ByVal and anum is passed ByRef.
Check the results on your screen to see what has happened.
Because num was passed ByVal, no changes were made to the variable - a copy of the variable was passed into the method.
And, as anum was passed ByRef, any changes made in the method body will still be in effect after the method has completed.
Now that you have seen what happens when you pass value types ByVal and ByRef, let's see what happens when we pass Reference Types (objects).
Create a new console project:
Module Module1
Class Person
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Public Sub New(ByVal name As String)
Me.Name = name
End Sub
End Class
Public Sub DoSomething(ByVal person1 As Person, _
ByRef person2 As Person)
person1.Name = "Changed Name"
person2.Name = "Also Changed"
Console.WriteLine("Inside Method:")
Console.WriteLine("Person1 Name: {0}", person1.Name)
Console.WriteLine("Person2 Name: {0}", person2.Name)
Console.WriteLine()
Person1 = Nothing
Person2 = Nothing
End Sub
Sub Main()
Dim p1 As New Person("Captain Cook")
Dim p2 As New Person("Vasco da Gama")
Console.WriteLine("Before Method Call:")
Console.WriteLine("Person1 Name: {0}", p1.Name)
Console.WriteLine("Person2 Name: {0}", p2.Name)
Console.WriteLine()
DoSomething(p1, p2)
Console.WriteLine("After Method Call:")
Console.WriteLine("Person1 Name: {0}", p1.Name)
Console.WriteLine("Person2 Name: {0}", p2.Name) ' NullReferenceException
Console.Read()
End Sub
Result:
Before Method Call:
Person1 Name: Captain Cook
Person2 Name: Vasco da Gama
Inside Method:
Person1 Name: Changed Name
Person2 Name: Also Changed
After Method Call:
Person1 Name: Changed Name
' Error here
We passed two Person parameters to the method DoSomething():
Dim p1 As New Person("Captain Cook")
Dim p2 as New Person("Vasco da Gama")
In the call to the method, the first argument p1 is passed ByVal, while the second argument p2 is passed ByRef as in the first example.
However, as the results show, the ByVal declaration is ignored and a copy of the Person object p1 is passed.
The beauty of passing a value type ByRef is that you can in-effect make a Sub into a "Function without a declared Return Type", and return more than one value from a Function!
| You must Sign In to use this message board. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||