Pierre
Pierre

Reputation: 1046

Reference and Value types

I have read that String was a "reference type", unlike integers. MS website

I tried to test its behavior.

Sub Main()
    Dim s As New TheTest
    s.TheString = "42"
    Dim z As String = s.GimmeTheString
    z = z & "000"
    Dim E As String = s.TheString
    s.GimmeByref(z)
end sub
Class TheTest
    Public TheString As String
    Public Function GimmeTheString() As String
        Return TheString
    End Function
    Public Sub GimmeByref(s As String)
        s = TheString
    End Sub
End Class

So I expected :

  1. z is same reference as TheString, thus TheString would be set to "42000"
  2. Then Z is modified by reference by GimmeByref thus Z is set to whatever TheString is

Actual result:

  1. Z="42000"
  2. E="42"
  3. TheString="42"

What point am I missing? I also tried adding "ByRef" in GimmeByRef : yes obviously the GimmeByRef does work as expected, but it also does if I put everything as Integer, which are said to be "Value type". Is there any actual difference between those types?

Upvotes: 1

Views: 145

Answers (2)

the_lotus
the_lotus

Reputation: 12748

Strings are immutable, every time you do a change it creates a new "reference" like if New was called.

A String object is called immutable (read-only), because its value cannot be modified after it has been created. Methods that appear to modify a String object actually return a new String object that contains the modification. Ref

Your code basically does something like this:

Sub Main()

    Dim a, b As String

    a = "12"
    b = a
    a = a & "13"

    Console.WriteLine(a) ' 1213
    Console.WriteLine(b) ' 12
    Console.ReadLine()

End Sub

Upvotes: 3

Konrad Rudolph
Konrad Rudolph

Reputation: 545518

The confusion comes about because regardless of type, argument passing in VB is pass by value by default.

If you want to pass an argument by reference, you need to specify the argument type as ByRef:

Public Sub GimmeByref(ByRef s As String)

You also need to understand the difference between mutating a value and re-assigning a variable. Doing s = TheString inside the method doesn’t mutate the value of the string, it reassigns s. This can obviously be done regardless of whether a type is a value or reference type.

The difference between value and reference types comes to bear when modifying the value itself, not a variable:

obj.ModifyMe()

Strings in .NET are immutable and thus don’t possess any such methods (same as integers). However, List(Of String), for instance, is a mutable reference type. So if you modify an argument of type List(Of String), even if it is passed by value, then the object itself is modified beyond the scope of the method.

Upvotes: 3

Related Questions