Parameter Passing

When an object's methods or an assembly's procedures and methods are called, it's often appropriate to provide input for the data to be operated on by the code. The values are referred to as parameters, and any object can be passed as a parameter to a Function or Sub.

When passing parameters, be aware of whether the parameter is being passed “by value” (ByVal) or “by reference” (ByRef). Passing a parameter by value means that if the value of that variable is changed, then when the Function/Sub returns, the system automatically restores that variable to the value it had before the call. Passing a parameter by reference means that if changes are made to the value of a variable, then these changes affect the actual variable and, therefore, are still present when the variable returns.

This is where it gets a little challenging for new Visual Basic developers. Under .NET, passing a parameter by value indicates only how the top-level reference (the portion of the variable on the stack) for that object is passed. Sometimes referred to as a shallow copy operation, the system copies only the top-level reference value for an object passed by value, and it is only this reference which is protected. This is important to remember because it means that referenced memory is not protected.

When you pass an integer by value, if the program changes the value of the integer, then your original value is restored. Conversely, if you pass a reference type, then only the location of your referenced memory is protected, not the data located within that memory location. Thus, while the reference passed as part of the parameter remains unchanged for the calling method, the actual values stored in referenced objects can be updated even when an object is passed by value.

In addition Visual Basic supports optional parameters. Optional parameters can be omitted by the calling code. This way, it is possible to call a method such as PadRight, passing either a single parameter defining the length of the string and using a default of space for the padding character, or with two parameters, the first still defining the length of the string but the second now replacing the default of space with a dash (code file: MainWindow.xaml.vb):

Public Sub PadRight(ByVal intSize as Integer, _
                         Optional ByVal chrPad as Char = " "c)
End Function

To use optional parameters, it is necessary to make them the last parameters in the function declaration. Visual Basic also requires that every optional parameter have a default value. It is not acceptable to merely declare a parameter and assign it the Optional keyword. In Visual Basic, the Optional keyword must be accompanied by a value that is assigned if the parameter is not passed in.

ParamArray

In addition to passing explicit parameters, it is also possible to tell Visual Basic that you would like to allow a user to pass any number of parameters of the same type. This is called a parameter array, and it enables a user to pass as many instances of a given parameter as are appropriate. For example, the following code creates a function Add, which allows a user to pass an array of integers and get the sum of these integers (code file: MainWindow.xaml.vb):

Public Function Add(ByVal ParamArray values() As Integer) As Long
    Dim result As Long
    For Each value As Integer In values
        result += value
    Next
    Return result
End Function

The preceding code illustrates a function (first shown at the beginning of this chapter without its implementation) that accepts an array of integers. Notice that the ParamArray qualifier is preceded by a ByVal qualifier for this parameter. The ParamArray requires that the associated parameters be passed by value; they cannot be optional parameters.

You might think this looks like a standard parameter passed by value except that it's an array, but there is more to it than that. In fact, the power of the ParamArray derives from how it can be called, which also explains many of its limitations. The following code shows two ways this method can be called (code file: MainWindow.xaml.vb):

Private Sub CallAdd()
    Dim int1 As Integer = 2
    Dim int2 = 3
    TextBox1.Text = "Adding 3 integers: " & Add(1, int1, int2) &
        Environment.NewLine
    Dim intArray() = {1, 2, 3, 4}
    TextBox1.Text &= "Adding an array of 4 integers: " & Add(intArray)
End Sub

The output from running this CallAdd method is shown in Figure 3.10. Notice that the first call, to the Add function, doesn't pass an array of integers; instead, it passes three distinct integer values. The ParamArray keyword tells Visual Basic to automatically join these three distinct values into an array for use within this method. The second call, to the Add method, actually leverages using an actual array of integers to populate the parameter array. Either of these methods works equally well. Arrays are covered in more detail in Chapter 7.

Figure 3.10 Using the function Add

3.10

Finally, note one last limitation of the ParamArray keyword: It can only be used on the last parameter defined for a given method. Because Visual Basic is grabbing an unlimited number of input values to create the array, there is no way to indicate the end of this array, so it must be the final parameter.

Variable Scope

The concept of variable scope encapsulates two key elements. In the discussion so far of variables, you have not focused on the allocation and deallocation of those variables from memory. Chapter 2 covers the release of variables and memory once it is no longer needed by an application, so this section is going to focus on the allocation and to some extent the availability of a given variable.

In order to make clear why this is important, consider an allocation challenge. What happens when you declare two variables with the same name but at different locations in the code? For example, suppose a class declares a variable called myObj that holds a property for that class. Then, within one of that class's methods, you declare a different variable also named myObj. What will happen in that method is determined by a concept called: Scope. Scope defines the lifetime and precedence of every variable you declare, and provides the rules to answer this question.

The first thing to understand is that when a variable is no longer “in scope,” it is available to the garbage collector for cleanup. This handles the deallocation of that variable and its memory. However, when do variables move in and out of scope?

.NET essentially defines four levels of variable scope. The outermost scope is global. Essentially, just as your source code defines classes, it can also declare variables that exist the entire time that your application runs. These variables have the longest lifetime because they exist as long as your application is executing. Conversely, these variables have the lowest precedence. Thus, if within a class or method you declare another variable with the same name, then the variable with the smaller, more local scope is used before the global version.

After global scope, the next scope is at the class or module level. When you add properties to a class, you are creating variables that will be created with each instance of that class. The methods of that class will then reference those member variables from the class, before looking for any global variables. Note that because these variables are defined within a class, they are visible only to methods within that class. The scope and lifetime of these variables is limited by the lifetime of that class, and when the class is removed from the system, so are those variables. More important, those variables declared in one instance of a class are not visible in other classes or in other instances of the same class (unless you actively expose them, in which case the object instance is used to fully qualify a reference to them).

The next shorter lifetime and smaller scope is that of method variables. When you declare a new variable within a method, such variables, as well as those declared as parameters, are only visible to code that exists within that module. Thus, the method Add wouldn't see or use variables declared in the method Subtract in the same class.

Finally, within a given method are various commands that can encapsulate a block of code (mentioned earlier in this chapter). Commands such as If Then and For Each create blocks of code within a method, and it is possible within this block of code to declare new variables. These variables then have a scope of only that block of code. Thus, variables declared within an If Then block or a For loop only exist within the constraints of the If block or execution of the loop. Creating variables in a For loop is a poor coding practice and performance mistake and should be avoided.

Variable scope is applicable whether you are working with one of the primitive types, a library class or a custom object. Recall that everything in .NET is represented as an object and all objects have scope, be it at the level of the application root or within a specific method.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset