Object-Oriented Programming with Visual Basic .NET

only for RuBoard

Data types fall into two categories: values types and reference types. Examples of value types include the built-in data types like Short , Integer , and Long ( System.Int16 , System.Int32 , and System.Int64 ). Value types are created on the stack, which is the area of memory that is local to a method. When the location is destroyed , the value type is destroyedthe garbage collector does not manage the stack.

Reference types are defined using classes and created on the heap, which is available for the lifetime of the object. The garbage collector manages this area of memory.

By default, both types are passed by value; a copy of the value is placed on the stack. Therefore, any changes made to a variable are local to the method. Example 3-4 demonstrates this concept.

Example 3-4. Passing parameters ByVal

Imports System Public Class App Private Class Counter Public Sub Increment(ByVal x As Integer) x += 1 End Sub End Class Public Shared Sub Main( ) Dim cc As New Counter( ) Dim x As Integer = 1 cc.Increment(x) Console.WriteLine(x.ToString( )) Console.WriteLine( ) Console.WriteLine("Hit ENTER to continue.") Console.ReadLine( ) End Sub End Class

When Example 3-4 is executed, the output will be 1 because a copy of x was passed to the Counter.Increment method. It is useful to use the ByVal keyword explicitly instead of relying on the default behavior:

Public Sub Increment(ByVal x As Integer)

Replacing ByVal with ByRef causes a reference to be passed instead of a copy. A reference is similar to a pointer. However, a reference should be thought of as an alias of a data type, not some arbitrary location in memory.

Public Sub Increment(ByRef x As Integer)

The output resulting from this change will be 2 .

3.5.1 A Word on Reference Types

Here is where things might get a little confusing. The previous example used a value type (an Integer ), and we saw that it was not modified after returning from the call to Counter.Increment . A reference typei.e., a type defined by a classis also passed as ByVal by default. What this means is that the actual reference is passed by value. The contents of the object can be changed, but as Example 3-5 shows, changing the reference to point to a different object instance has only a local effect.

Example 3-5. Passing references by value

Imports System Public Class Message Private myText As String Public Property Text( ) As String Get Return myText End Get Set(ByVal Value As String) myText = value End Set End Property End Class Public Class ReferenceTest Public Sub New( ) Dim A As New Message( ) A.Text = "I am object A" Dim B As New Message( ) B.Text = "I am object B" SwitchRef(A, B) Console.WriteLine(A.Text) Console.WriteLine(B.Text) End Sub Private Sub SwitchRef(ByVal A As Message, _ ByVal B As Message) A = B A.Text = "I am still object B but changed" End Sub End Class Public Class App Public Shared Sub Main( ) Dim refTest As New ReferenceTest( ) End Sub End Class

Here's what is going on. In ReferenceTest , two distinct objects, A and B , are passed to the SwitchRef method. Inside this method, A is aliased to object B . When A.Text is called, the text for object B is actually being changed. This process is verified upon return when the text for object A and B is written to the console. The output looks like this:

I am object A I am still object B but changed

More confusing still are strings. Strings are reference types, but because strings are immutable, strings passed ByVal behave as value types and strings passed ByRef , when modified, actually return a different object instance.

only for RuBoard

Категории