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!

Leave a Reply