Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations John Tel on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Totally confused ByVal 1

Status
Not open for further replies.

dragonwell

Programmer
Oct 21, 2002
863
US
OK, this is very embarrasing, having used VB.NET for almost two years now, and thinking I knew the difference between ByVal and ByRef in passing parameters.

The way I understand it, if you pass a reference type to a function ByVal, you are passing the reference to that object (and not a by-value copy). This seems to make sense by this test:
Code:
Class MyClass
    Public Name As String = ""
End Class

Sub Test(ByVal x as MyClass)
    x.Name = "Name Set ByVal"
End Sub

Sub Main()
    Dim instance as MyClass = new MyClass()
    Test(instance)
    Console.WriteLine(instance.Name)
End Sub

[green]'output: Name Set ByVal[/green]

OK, now what about this:
Code:
Class MyClass
    Public Name As String = ""
End Class

Sub Test(ByVal x as MyClass)
   x.Name = "Name Set ByVal"
   [b]x = Nothing[/b]
Sub Main()
    Dim instance as MyClass = new MyClass()
    Test(instance)
    Console.WriteLine(instance.Name)
End Sub

[green]'output: Name Set ByVal
'expected: Null Reference Exception[/green]

What!? If in Sub Test, I have a reference to the instance of MyClass, should I not be able to destroy that reference as well??

I just don't get it.

 
ByVal sample:
Code:
Public Sub Main
  dim x as integer
  x = 0
  DoThing(x)
  msgbox(x)
end sub

Public Sub DoThing(byval value as Integer)
  Value = 999
end sub
You should see a message box with "0"



ByRef sample:
Code:
Public Sub Main
  dim x as integer
  x = 0
  DoThing(x)
  msgbox(x)
end sub

Public Sub DoThing(byref value as Integer)
  Value = 999
end sub

You should see a message box with "999"

-Rick

VB.Net Forum forum796 forum855 ASP.NET Forum
[monkey]I believe in killer coding ninja monkeys.[monkey]
 
In descriptive terms, ByVal passes a copy of the variable's value. ByRef passes a reference to the memory location of the variable.

If you set a parameter value that was passed byRef to Nothing, then the variable that was passed in the parent sub will also be set to nothing as they both are referenced by the same memory address.

-Rick

VB.Net Forum forum796 forum855 ASP.NET Forum
[monkey]I believe in killer coding ninja monkeys.[monkey]
 
I understand that with an Integer, since Integer is a Value type. But with a reference type (MyClass), you DO mutate the parameter. But it is becoming clear to me now that even though you can mutate it, you cannot completely replace it. For example:
Code:
Class MyClass
   Public Name As String = ""
End Class MyClass

Sub Test(ByVal x As MyClass)
  x.Name = "Test"
  x = New MyClass()
  x.Name = "renamed"
End Sub 
   
Sub Main()

   Dim instance As MyClass = New MyClass()
      
   Test(instance)
      
   Console.WriteLine(instance.Name)

End Sub 

'output: "Test"

So, when you want to mutate an object within a method, it's ok to pass ByVal. But to do anything to the actual reference to the parameter, you must use ByRef.

I did not know that.
 
Correct, changing this to ByRef should reflect the changes made to x in to sub text on the object "instance" in sub main.

Code:
Class MyClass
   Public Name As String = ""
End Class MyClass

Sub Test(ByRef x As MyClass)
  x.Name = "Test"
  x = New MyClass()
  x.Name = "renamed"
End Sub
   
Sub Main()

   Dim instance As MyClass = New MyClass()
      
   Test(instance)
      
   Console.WriteLine(instance.Name)

End Sub

'output: "renamed"

-Rick

VB.Net Forum forum796 forum855 ASP.NET Forum
[monkey]I believe in killer coding ninja monkeys.[monkey]
 
Right - it's the difference between doing something to the values owned by an instance, and replacing the instance itself.

Currently, there's no way to prevent some code from changing a property on an instance, even if passed ByVal.

Chip H.


____________________________________________________________________
If you want to get the best response to a question, please read FAQ222-2244 first
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top