ByVal Gotcha - Don’t Fall For It (VB.NET)
It came up again on the forums. Someone passed an object (a generic list this time) to a property setter of an object, then got surprised when it became corrupted unpredictably.
ByVal is a fooler. It in no way affects the behavior of reference types or value types. Value types will pass a copy of their data, as normal. Reference types will pass a copy of the pointer to the address in the memory heap of their data. If you pass a reference type object to a method or property, you’re getting a pointer.
What does this all mean? It means if you try passing around an object, it might end up modified in fun and interesting ways. Here is example code. Check it out and see the fun. The animals list changes. The colors list won’t.
Class code:
Imports System.Collections.Generic Imports System.IO Public Class TestClass Private _animals As List(Of String) Public Property Animals() As List(Of String) Get Return _animals End Get Set(ByVal value As List(Of String)) _animals = value End Set End Property Private _colors As List(Of String) Public Property Colors() As List(Of String) Get Return _colors End Get Set(ByVal value As List(Of String)) _colors = New List(Of String) For Each x As String In value _colors.Add(x) Next End Set End Property Public Sub PrintAnimals() For Each x As String In _animals Console.WriteLine(x) Next End Sub Public Sub PrintColors() For Each x As String In _colors Console.WriteLine(x) Next End Sub End Class
Console test code:
Imports System.Collections.Generic Module Module1 Sub Main() Dim test As TestClass = New TestClass Dim animalList As List(Of String) = New List(Of String) animalList.Add("ape") animalList.Add("dog") animalList.Add("cat") animalList.Add("goat") test.Animals = animalList Console.WriteLine("animal list before: ") test.PrintAnimals() animalList.Remove("ape") animalList.Remove("goat") Console.WriteLine("animal list after: ") test.PrintAnimals() Console.WriteLine() Dim colorList As List(Of String) = New List(Of String) colorList.Add("blue") colorList.Add("green") colorList.Add("purple") colorList.Add("red") test.Colors = colorList Console.WriteLine("color list before: ") test.PrintColors() colorList.Remove("green") colorList.Remove("purple") Console.WriteLine("color list after: ") test.PrintColors() Console.Read() End Sub End Module
Happy coding!

