VB.Net: Passing Reference and Value Objects ByRef and ByVal

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


 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s