Section 9.3. Passing by Value and by Reference

   

9.3 Passing by Value and by Reference

Visual Basic .NET differentiates between value types and reference types . All the intrinsic types (Integer, Long, etc.), as well as structs (described in Chapter 12) are value types. Classes and interfaces (described in Chapter 8 and Chapter 13, respectively) are reference types.

9.3.1 Passing Arguments by Value

In many of the method calls shown in the previous chapters, the parameters were marked with the keyword ByVal . This indicates that the arguments are passed to the method by value; that is, a copy of the argument is passed to the method. Examine the code in Example 9-3. Try to guess what the output will be before reading further.

Example 9-3. Using the ByVal parameter
 Option Strict On Imports System Public Class Tester    Public Sub Run( )       ' declare a variable and initialize to 5       Dim theVariable As Integer = 5       ' display its value       Console.WriteLine("In Run. theVariable: {0}", _       theVariable)       ' call a method and pass in the variable       Doubler(theVariable)       ' return and display the value again       Console.WriteLine("Back in Run. theVariable: {0}", _       theVariable)    End Sub    Public Sub Doubler(ByVal param As Integer)       ' display the value that was passed in       Console.WriteLine("In Method1. Received param: {0}", _       param)       'Double the value       param *= 2       ' Display the doubled value before returning       Console.WriteLine( _       "Updated param. Returning new value: {0}", _       param)    End Sub End Class 'Tester Module Module1    Sub Main( )       Dim t As New Tester( )       t.Run( )    End Sub End Module 

In Example 9-3, the Main( ) method does nothing but instantiate a Tester object and call Run( ). In Run( ), you create a local variable, theVariable, and initialize its value to 5, which you then display:

 Dim theVariable As Integer = 5 Console.WriteLine("In Run. theVariable: {0}", _ theVariable) 

You pass theVariable to the Doubler( ) method, which displays the value, doubles it, and then redisplays it before returning:

 Public Sub Doubler(ByVal param As Integer)    Console.WriteLine("In Method1. Received param: {0}", _    param)    param *= 2    Console.WriteLine( _    "Updated param. Returning new value: {0}", _    param) End Sub 

When you return from the call to Doubler( ), you display the value of theVariable again. What is the value that is now displayed?

 Console.WriteLine("Back in Run. theVariable: {0}", _ theVariable) 

As shown in the output, the value of the variable that was passed in to Doubler( ) is, in fact, doubled in the Doubler( ) method but is unchanged in the calling method (Run):

 In Run. theVariable: 5 In Method1. Received param: 5  Updated param. Returning new value: 10   Back in Run. theVariable: 5  

The value of the parameter was passed by value, and thus a copy was made in the Doubler( ) method. This copy was doubled, but the original value was unaffected.

9.3.2 Passing Arguments by Reference

Visual Basic .NET also supports passing arguments by reference using the ByRef keyword. You can test this by making one tiny change to Example 9-3, changing the parameter of Doubler( ) from ByVal to ByRef :

 Public Sub Doubler(ByRef param As Integer) 

The rest of the program remains completely unchanged. Run the program again and compare the new output with the original:

 In Run. theVariable: 5 In Method1. Received param: 5 Updated param. Returning new value: 10  Back in Run. theVariable: 10  

The value of the argument to the method is now passed by reference. That is, rather than a copy being made, a reference to the object itself is passed, as illustrated in Figure 9-1. The object referred to by param is now the variable declared in Run( ). Thus, when you change it in Doubler( ), the change is reflected back in the Run( ) method.

Figure 9-1. Passing arguments by reference
figs/lvbn_0901.gif

9.3.3 Passing Reference Types by Value

In Chapter 8, you saw how you can create a copy of a reference to an object and then have the two references refer to the same object. Similarly, when you pass a reference as a parameter, a copy of the parameter is made, but that is a copy of a reference, and the two references refer to the same object. You can see the effect by modifying Example 9-3 to pass an object, rather than an Integer, by value. The complete listing is shown in Example 9-4. An analysis follows the output.

Example 9-4. Passing a reference as a parameter
 Option Strict On Imports System Public Class Cat    Private mWeight As Integer    Public Sub New(ByVal weight As Integer)       mWeight = weight    End Sub    Public Property Weight( ) As Integer       Get          Return mWeight       End Get       Set(ByVal Value As Integer)          mWeight = Value       End Set    End Property    Public Overrides Function ToString( ) As String       Return mWeight.ToString( )    End Function End Class Public Class Tester    Public Sub Run( )       ' declare a Cat and initialize to 5       Dim theVariable As New Cat(5)       ' display its value       Console.WriteLine("In Run. theVariable: {0}", _       theVariable)       ' call a method and pass in the variable       Doubler(theVariable)       ' return and display the value again       Console.WriteLine("Back in Run. theVariable: {0}", _       theVariable)    End Sub    Public Sub Doubler(ByVal param As Cat)       ' display the value that was passed in       Console.WriteLine("In Method1. Received param: {0}", _       param)       'Double the value       param.Weight = param.Weight * 2       ' Display the doubled value before returning       Console.WriteLine( _       "Updated param. Returning new value: {0}", _       param)    End Sub End Class 'Tester Module Module1    Sub Main( )       Dim t As New Tester( )       t.Run( )    End Sub End Module 
  Output:  In Run. theVariable: 5 In Method1. Received param: 5 Updated param. Returning new value: 10 Back in Run. theVariable: 10 

Example 9-4 begins by defining a very simple Cat class:

 Public Class Cat 

The class has a single private member variable, mWeight, and a property (Weight) to get and set the value of that variable:

 Private mWeight As Integer Public Property Weight( ) As Integer    Get       Return mWeight    End Get    Set(ByVal Value As Integer)       mWeight = Value    End Set End Property 

The constructor allows you to initialize a Cat object by passing in an integer value for its weight:

 Public Sub New(ByVal weight As Integer)    mWeight = weight End Sub 

Finally, you override the ToString( ) method so that when you display the Cat object, its weight is displayed:

 Public Overrides Function ToString( ) As String    Return mWeight.ToString( ) End Function 

Overriding methods is explaned in detail in Chapter 13. For now, you can use this method as shown to allow you to pass the Cat object to WriteLine( ) and have the weight displayed.

Example 9-4 changes Example 9-3 as little as possible. The Run( ) method still creates a local object named theVariable, but this time it is a Cat rather than an Integer:

 Dim theVariable As New Cat(5) 

The value of theVariable is displayed and then passed to the Doubler( ) method:

 Console.WriteLine("In Run. theVariable: {0}", _ theVariable) Doubler(theVariable) 

In Example 9-4, the Doubler( ) method is changed to make the parameter be a Cat rather than an Integer. Note that the parameter is marked ByVal . The Cat reference will be passed by value, and a copy of the reference will be made:

 Public Sub Doubler(ByVal param As Cat) 

Within Doubler( ), the value of the parameter is displayed, doubled, and then displayed again:

 Console.WriteLine("In Method1. Received param: {0} param) param.Weight = param.Weight * 2 Console.WriteLine( _ "Updated param. Returning new value: {0}", _ param) 

Back in Run( ), the value of theVariable is displayed:

 Console.WriteLine("Back in Run. theVariable: {0}", _ theVariable) 

This is identical to Example 9-3 in which the integer value of theVariable was unchanged after returning from Doubler( ). This time, however, the value is changed, even though the object was passed by value. The difference is that integers are value types, and classes are reference types.

   


Learning Visual Basic. NET
Learning Visual Basic .Net
ISBN: 0596003862
EAN: 2147483647
Year: 2002
Pages: 153
Authors: Jesse Liberty

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net