Here is a little example of how vb.net deals with passing of objects ByRef and ByVal. The short answer is that when you pass a reference type object (not a value type) byval, the object is copied back when the method if finished. You never really have handle on the original object, which is evident by the fact that you can’t set it = nothing. However, if you pass ByRef then you can indeed set the object = nothing and it will remain null when you return to the calling function.
If you try the same thing, except using a value type structure, you will see almost the same behavior, except for the major differenct that if you pass a structure byval and then make a change to it, those changes will not be copied back to the calling function.
To see an example of this check out the code by clicking on the “More” button to read the full article.
You can take this code and run it as a console app to see the results, which should be:
SetNothingByVal: Object was not cleared SetNothingByRef: Object was cleared ChangeFieldByVal: Object WAS modified ChangeFieldByRef: Object WAS modified SetStructToNothingByVal was NOT able to null out the structure SetStructToNothingByRef was able to null out the structure SetStructToNothingByVal was NOT able to change the structure SetStructToNothingByRef was able to null change structure
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections
Public Class SomeObject
Public MyField As String
End Class
Public Structure SomeValueType
Public MyField As Integer
End Structure
Public Module MyModule
Sub Main()
RL()
TryToNullAnObject()
TryToModifyObject()
TryToNullStructure()
TryToModifyStructure()
RL()
End Sub
#Region "TryToModifyStructure"
Private Sub TryToModifyStructure()
Dim s As SomeValueType
s.MyField = 1
Call ChangeStructByVal(s)
If s.MyField <> 1 Then
WL("SetStructToNothingByVal was able to change the structure")
Else
WL("SetStructToNothingByVal was NOT able to change the structure")
End If
Call ChangeStructByRef(s)
If s.MyField <> 1 Then
WL("SetStructToNothingByRef was able to null change structure")
Else
WL("SetStructToNothingByRef was NOT able to null change structure")
End If
End Sub
#End Region
#Region "TryToNullStructure"
Private Sub TryToNullStructure()
Dim s As SomeValueType
s.MyField = 1
If s.MyField = Nothing Then
WL("before we even start, we are at nothing")
End If
Call SetStructToNothingByVal(s)
If s.MyField = Nothing Then
WL("SetStructToNothingByVal was able to null out the structure")
Else
WL("SetStructToNothingByVal was NOT able to null out the structure")
End If
Call SetStructToNothingByRef(s)
If s.MyField = Nothing Then
WL("SetStructToNothingByRef was able to null out the structure")
Else
WL("SetStructToNothingByRef was NOT able to null out the structure")
End If
End Sub
#End Region
#Region "TryToNullAnObject"
Public Sub TryToNullAnObject()
Dim o As New SomeObject
o.MyField = "test"
Call SetNothingByVal(o)
If o Is Nothing Then
WL("SetNothingByVal: Object was cleared")
Else
WL("SetNothingByVal: Object was not cleared")
End If
Call SetNothingByRef(o)
If o Is Nothing Then
WL("SetNothingByRef: Object was cleared")
Else
WL("SetNothingByRef: Object was not cleared")
End If
End Sub
#End Region
#Region "TryToModifyObject"
Private Sub TryToModifyObject()
Dim o As New SomeObject
o.MyField = "test"
Call ChangeFieldByVal(o)
If o.MyField = "test" Then
WL("ChangeFieldByVal: Object was not modified")
Else
WL("ChangeFieldByVal: Object WAS modified")
End If
Call ChangeFieldByRef(o)
If o.MyField = "test" Then
WL("ChangeFieldByRef: Object was not modified")
Else
WL("ChangeFieldByRef: Object WAS modified")
End If
End Sub
#End Region
#Region "Functions to do all the testing"
Public Sub SetNothingByRef(ByRef o As SomeObject)
o = Nothing
End Sub
Public Sub SetNothingByVal(ByVal o As SomeObject)
o = Nothing
End Sub
Public Sub ChangeFieldByRef(ByRef o As SomeObject)
o.MyField = "changed"
End Sub
Public Sub ChangeFieldByVal(ByVal o As SomeObject)
o.MyField = "changed"
End Sub
Public Sub SetStructToNothingByRef(ByRef o As SomeValueType)
o = Nothing
End Sub
Public Sub SetStructToNothingByVal(ByVal o As SomeValueType)
o = Nothing
End Sub
Public Sub ChangeStructByRef(ByRef o As SomeValueType)
o.MyField = 123
End Sub
Public Sub ChangeStructByVal(ByVal o As SomeValueType)
o.MyField = 123
End Sub
#End Region
#Region "Helper methods"
Sub WL(ByVal text As Object)
Console.WriteLine(text)
End Sub
Sub WL(ByVal text As Object, ByVal ParamArray args As Object())
Console.WriteLine(text.ToString(), args)
End Sub
Sub RL()
Console.ReadLine()
End Sub
Sub Break()
System.Diagnostics.Debugger.Break()
End Sub
#End Region
End Module