Exploring the Modularizing Control Structures: Subroutines and Functions


The code examples we looked at in this hour and the preceding one have all been a few simple lines of code designed to illustrate the concept being discussed. In examining the execution of these code samples, we discussed how Visual Basic interprets one line of code at a time, starting with the first line and working down. With control structures, however, this sequential flow of instructions can be altered, such as with loops or conditional statements.

In addition to altering the flow control with loops and conditionals, Visual Basic allows for modularizing control structures. A modularizing control structure is a control structure that can be used to create a module of source code. This module may contain many lines of source code, can accept zero to many input parameters, and can optionally return a value. Furthermore, these modules can then be called from any location in the Visual Basic source code.

There are two flavors of modularization control structures: subroutines and functions. Subroutines are modularization control structures that do not return any value, whereas functions always return a value. Subroutines and functions are handy for encapsulating programming logic.

To understand subroutines and functions, let's look at a somewhat contrived example that utilizes a subroutine to encapsulate the logic behind displaying a repeated text message. Start by creating a new ASP.NET web page named SubroutineLesson1.aspx. Add a Label Web control to the page's HTML portion, clearing out its Text property and settings its ID property to output. Next, create an event handler for the page's Load event. Now, we want this ASP.NET page to display the string "Welcome to my Website" precisely four times. To accomplish this, we can use a simple For loop that concatenates the string "Welcome to my Website" to the output Label's Text property in the loop body.

Listing 6.2 contains the source code that you should enter into the page's source code portion.

Listing 6.2. The Page_Load Event Handler Displays a Message Four Times

[View full width]

 1:  Partial Class SubroutineLesson1  2:     Inherits System.Web.UI.Page  3:  4:     Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)  Handles Me.Load  5:         output.Text = String.Empty  6:  7:         Dim i As Integer  8:         For i = 1 To 4  9:             output.Text &= "Welcome to my Website<br />" 10:         Next i 11:     End Sub 12:  End Class 

Notice that on line 5 we clear out the Label Web control's Text property programmatically. We accomplish this by setting the Text property to an empty string. An empty string can be denoted in one of two ways: using String.Empty, as on line 5, or using a string literal with no contents (""). That is, the code's output would be identical if we replaced line 5 with output.Text = "".

After you have entered this code, view the page through a browser. Notice that this web page displays the message "Welcome to my Website" four times, as shown in Figure 6.2.

Figure 6.2. The "Welcome to my Website" message is displayed four times.


Now, imagine that we also wanted a Button Web control on the web page that, when clicked, would display the message "Welcome to my Website" four times as well.

To accomplish this, we first need to add a Button Web control. To do this, return to the HTML portion of the ASP.NET page and drag and drop a Button Web control from the Toolbox onto the page. At this point your screen should look similar to Figure 6.3.

Figure 6.3. A Button Web control has been added.


To add an event handler for the Button's Click event, either double-click on the Button Web control from the Design view or go to the code portion and select the Button Web control from the left drop-down list and its Click event from the drop-down list on the right. Either of these approaches will automatically add the appropriate event handler syntax. Recall from our discussions in Hour 4, "Designing, Creating, and Testing ASP.NET Web Pages," that when the Button is clicked, the Button's Click event handler is executed. Therefore, to have the message "Welcome to my Website" displayed four times when the Button is clicked, we want to place the same code that appears in the Page_Load event handler in the Button's Click event handler.

Listing 6.3 contains the ASP.NET page's source code portion with the added Click event handler (lines 11 through 16), which you should enter.

Listing 6.3. The Message Is Displayed Four Times When the Button Web Control Is Clicked

[View full width]

 1: Partial Class SubroutineLesson1  2:     Inherits System.Web.UI.Page  3:  4:     Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)  Handles Me.Load  5:         output.Text = String.Empty  6:  7:         Dim i As Integer  8:         For i = 1 To 4  9:             output.Text &= "Welcome to my Website<br />" 10:         Next i 11:     End Sub 12: 13:     Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs)  Handles Button1.Click 14:         Dim i As Integer 15:         For i = 1 To 4 16:             output.Text &= "Welcome to my Website<br />" 17:         Next i 18:     End Sub 19: End Class 

With this addition to the ASP.NET web page, when you first visit the web page, the message "Welcome to my Website" is displayed four times (from the Page_Load event handler). Additionally, a Button is displayed. Figure 6.4 shows SubroutineLesson1.aspx after the code from both Listings 6.2 and 6.3 has been added to the source code portion.

Figure 6.4. A Button Web control is displayed after the message.


When the Button Web control is clicked, the ASP.NET page is posted back, which causes the Button's Click event handler to fire. In addition to the Button's Click event handler being executed, the Page_Load event handler is executed as well because the page is being loaded again. This causes the message "Welcome to my Website" to be displayed eight times, as shown in Figure 6.5.

Figure 6.5. The "Welcome to my Website" message is displayed eight times after the button is clicked.


By the Way

Recall that in Hour 4, we briefly discussed the series of actions that happen when a Button Web control is clicked. If you are still a bit confused or unclear, don't worry; we'll be covering this topic in much greater detail in Hour 9, "Web Form Basics."


Reducing Code Redundancy Using Subroutines and Functions

Although the code for our ASP.NET web page is fairly simple, it contains redundancies. The code to display the "Welcome to my Website" message is repeated twice: once in the Page_Load event handler and once in the Button's Click event handler. We can use a subroutine to reduce this redundancy.

We can create a subroutine using the following syntax:

Sub SubroutineName()   Instruction1   Instruction2   ...   InstructionN End Sub 


The code that appears between the Sub and End Sub lines is referred to as the body of the subroutine and is executed whenever the subroutine is called. A subroutine is called using the following syntax:

SubroutineName() 


For our ASP.NET Web page, we can create a subroutine named DisplayMessage() that has as its body the code to display the "Welcome to my Website" message four times. Then, in the Page_Load and the Button's Click event handlers, we can replace the code that displays the message four times with a call to the DisplayMessage() subroutine.

To employ a subroutine to display the message, replace the source code contents entered from Listings 6.2 and 6.3 with the source code provided in Listing 6.4.

Listing 6.4. The Code to Display the "Welcome to my Website" Message Is Moved to a Subroutine

[View full width]

 1: Partial Class SubroutineLesson1  2:     Inherits System.Web.UI.Page  3:  4:     Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)  Handles Me.Load  5:         output.Text = String.Empty  6:  7:         DisplayMessage()  8:     End Sub  9: 10:     Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs)  Handles Button1.Click 11:         DisplayMessage() 12:     End Sub 13: 14:     Private Sub DisplayMessage() 15:         Dim i As Integer 16:         For i = 1 To 4 17:             output.Text &= "Welcome to my Website<br />" 18:         Next i 19:     End Sub 20: End Class 

Listing 6.4 has encapsulated the code to display the "Welcome to my Website" message four times in a subroutine (lines 1419). The body of the subroutine can be invoked from anywhere else in the ASP.NET source code portion by calling the subroutine (see lines 7 and 11).

View it through a browser by going to the Debug menu and choosing Start Without Debugging. Upon first loading the page, you should see the same output shown in Figure 6.4: the message "Welcome to my Website" displayed four times, followed by a Button. By clicking on the Button, you should see the output shown in Figure 6.5: the message "Welcome to my Website" displayed eight times, followed by a Button.

Did you Know?

Strive to reduce code redundancy by modularizing repeated code into a subroutine or function. Redundant code has a number of disadvantages, such as making the code harder to read (due to its increased length), harder to update (because changes to the redundant code require updating the code in multiple places), and more prone to typos (because you have to reenter the code multiple times, the chances of making a mistake increase).


Passing in Parameters to a Subroutine or Function

In Listing 6.4 we used a subroutine to display a message four times. Specifically, the message Welcome to my Website was displayed in a Label Web control through a For loop. But what if we wanted to generalize the DisplayMessage() subroutine so that instead of always displaying the message "Welcome to my Website", any message could be displayed four times?

Subroutines and functions can be generalized in this manner through the use of parameters. A parameter is a value that is passed into a subroutine or function when the subroutine or function is called. For a subroutine or function to utilize parameters, the syntax used differs in that a list of the parameters the subroutine or function accepts must be added, as in the following code:

Sub SubroutineName(Param1 as Type, Param2 as Type, ... ParamN as Type)   Instruction1   Instruction2   ...   InstructionN End Sub 


Param1 through ParamN are referred to as the subroutine's parameters. A subroutine may have zero to many parameters. Because Visual Basic is a strongly typed language, each parameter must have a type. The instructions in the subroutine's body can access these parameters just like they would any other variable.

Let's take a moment to rewrite the DisplayMessage() subroutine from Listing 6.4 so that any message can be displayed four times. To accomplish this, the DisplayMessage() subroutine needs to accept a string parameter that indicates the message to display. This updated version of the DisplayMessage() subroutine is as follows:

Private Sub DisplayMessage(ByVal message as String)   'Display the message, "Welcome to my Website" 4 times   Dim i as Integer   For i = 1 to 4     output.Text &= message   Next i End Sub 


With this change, the DisplayMessage() subroutine accepts a parameter message of type String. In the subroutine's body, instead of using output &= "Welcome to my Website<br />", which would display the message "Welcome to my Website", we'll use output &= message, which emits the value of the message variable.

To call this updated version of the DisplayMessage() subroutine, we use the following code:

DisplayMessage(messageToDisplay) 


So, if we want to display the message "Welcome to my Website", we would call the subroutine like this:

DisplayMessage("Welcome to my Website<br>") 


Let's use this updated version of the DisplayMessage() subroutine to create a page whose output is exactly identical to that of Listing 6.4. Start by creating a new ASP.NET web page named SubroutineLesson2.aspx. As with SubroutineLesson1.aspx, add a Label Web control with ID output and a Button Web control. Also, be sure to create the event handlers for the page's Load event and the Button's Click event. After you have done this, enter the source code in Listing 6.5.

Listing 6.5. The DisplayMessage() Subroutine Accepts a Parameter

[View full width]

 1: Partial Class SubroutineLesson2  2:     Inherits System.Web.UI.Page  3:  4:     Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)  Handles Me.Load  5:         output.Text = String.Empty  6:  7:         DisplayMessage("Welcome to my Website<br />")  8:     End Sub  9: 10:     Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs)  Handles Button1.Click 11:         DisplayMessage("Welcome to my Website<br />") 12:     End Sub 13: 14:     Private Sub DisplayMessage(ByVal message As String) 15:         Dim i As Integer 16:         For i = 1 To 4 17:             output.Text &= message 18:         Next i 19:     End Sub 20: End Class 

When viewing this page through a browser, you should initially see the same output shown in Figure 6.4: the message "Welcome to my Website" displayed four times, followed by a Button. By clicking on the Button, you should see the output shown in Figure 6.5: the message "Welcome to my Website" displayed eight times, followed by a Button.

Did you Know?

A subroutine or function may have more than one parameter. To create a subroutine with multiple parameters, simply list the parameters and their types using a comma to separate each parameter.


By the Way

Each subroutine's or function's parameter has a keyword that specifies low-level details on how the parameter is sent from the caller to the subroutine or function. There are two possible values: ByVal and ByRef. A thorough discussion of these two keywords and the effects they have is beyond the scope of this book. For all examples in this book, we'll be using ByVal, which is the default. In fact, when typing in the subroutine or function parameters, you can omit the ByVal keyword; Visual Web Developer will add it automatically.


Returning Values with Functions

At this point we've looked only at subroutines, so you may be wondering what, exactly, the differences are between subroutines and functions. Subroutines and functions actually have quite a bit in common. Both are modularization control structures, and both can have zero to many parameters. Both are used to reduce code redundancy and to enhance encapsulation of programming logic.

The main difference between subroutines and functions is that a function returns a resulting value, whereas a subroutine does not. In Listing 6.5, we looked at creating a DisplayMessage() subroutine that used a For loop to display the passed-in string parameter four times. Because no resulting value is returned, we used a subroutine. But what if we wanted to modularize some programming logic that performed some sort of calculation.

In Hour 4 we created a financial calculator web page. This page accepted some inputsthe user's home loan amount, the interest rate, and so onand determined the monthly cost. This was accomplished in a little less than 20 lines of code and was coded directly in the Click event handler for the Web page's Button Web control.

A more modular approach would be to place this logic in a function and then have the Click event handler call the function.

When creating a function, realize that a function's syntax differs from a subroutine's syntax in a few ways. First, instead of using the Sub ... End Sub keywords, we use Function and End Function. Second, because a function returns a value, we must specify the type of the value returned by the function. Finally, in the function body, we need to actually return some value. This is accomplished via the Return keyword.

The general syntax of a function is as follows:

Function FunctionName(Param1 as Type, ..., ParamN as Type) as ReturnType   Instruction1   Instruction2   ...   InstructionN End Function 


The ReturnType specifies the type of the value returned by the function. As with subroutines, functions can have zero to many input parameters. Functions are called in an identical fashion to subroutines, except that because functions return a value, often you will be using a function call in an expression, like the following:

Dim costPerMonth as Double costPerMonth = ComputeCostPerMonth(P, r, t) 


Here ComputeCostPerMonth() is a function that accepts three inputs and returns a Double value. Typically, you will assign the result of a function to a variable, although you can call a function and disregard its result, as in

ComputeCostPerMonth(P, r, t) 'disregards the return value 


Let's create a function to compute the monthly cost of a mortgage. If you created the FinancialCalculator.aspx web page from Hour 4, you can cut and paste the source code from the performCalc_Click event handler into the new function, ComputeCostPerMonth(). The code for the new function is given in Listing 6.6.

Listing 6.6. The ComputeCostPerMonth() Function Computes the Monthly Cost of a Mortgage

 1: Private Function ComputeMonthlyCost(P as Double, r as Double, t as Double) as Double  2:   'Specify constant values  3:   Const INTEREST_CALCS_PER_YEAR as Integer = 12  4:   Const PAYMENTS_PER_YEAR as Integer = 12  5:  6:   Dim ratePerPeriod as Double  7:   ratePerPeriod = r/INTEREST_CALCS_PER_YEAR  8:  9:   Dim payPeriods as Integer 10:   payPeriods = t * PAYMENTS_PER_YEAR 11: 12:   Dim annualRate as Double 13:   annualRate = Math.Exp(INTEREST_CALCS_PER_YEAR * Math.Log(1+ratePerPeriod)) - 1 14: 15:   Dim intPerPayment as Double 16:   intPerPayment = (Math.Exp(Math.Log(annualRate+1)/payPeriods) - 1) * payPeriods 17: 18:   'Now, compute the total cost of the loan 19:   Dim intPerMonth as Double = intPerPayment / PAYMENTS_PER_YEAR 20: 21:   Dim costPerMonth as Double 22:   costPerMonth = P * intPerMonth/(1-Math.Pow(intPerMonth+1,-payPeriods)) 23: 24:   Return costPerMonth 25: End Function 

The ComputeMonthyCost() function accepts three parameters, all of type Double, and returns a value of type Double. Recall from Hour 4 that to compute the monthly cost of a mortgage, we need three bits of information: the mortgage principal (P), the interest rate (r), and the duration of the mortgage (t). The ComputeMonthyCost() function receives these three values and uses them to compute the monthly mortgage cost. It then returns this final value using the Return statement (line 24).

By the Way

The code in Listing 6.6 from lines 2 through 22 was taken directly from the performCalc_Click event handler in the FinancialCalculator.aspx page created in Hour 4.


Now that we have the ComputeMonthyCost() function written, we can call it from the performCalc_Click event handler, which is the event handler that fires whenever the page's Button Web control is clicked. The event handler's code replaces the computation with a call to ComputeMonthyCost(), as shown in Listing 6.7.

Listing 6.7. The performCalc_Click Event Handler Calls the ComputeMonthyCost() Function

[View full width]

1: Protected Sub performCalc_Click(ByVal sender As Object, ByVal e As System.EventArgs)  Handles performCalc.Click 2:   'Create variables to hold the values entered by the user 3:   Dim P as Double = loanAmount.Text 4:   Dim r as Double = rate.Text / 100 5:   Dim t as Double = mortgageLength.Text 6: 7:   results.Text = "Your mortgage payment per month is $" & ComputeMonthlyCost(P, r, t) 8: End Sub 

On lines 35, the values entered by the user into the loan amount, interest rate, and mortgage length TextBox Web controls are read and stored into local variables P, r, and t. Then, on line 7, the Text property of the results Label is assigned the string "Your mortgage payment per month is $", concatenated with the Double value returned by ComputeMonthyCost().

Watch Out!

If you have the Strict="True" setting specified, the code in Listing 6.7 will generate an error because lines 3, 4, and 5 use implicit casting to cast a String (loanAmount.Text, rate.Text, and mortgageAmount.Text) into a Double. If you are using Strict="True", you will need to use the Convert.ToDouble() method to convert the Strings to Doubles, like so:

Dim P as Double = Convert.ToDouble(loanAmount.Text) 



Where Do Event Handlers Fit In?

As we discussed in the "Exploring the Modularizing Control Structures: Subroutines and Functions" section, Visual Basic has two forms of modularization control structures: subroutines and functions. In this hour we looked at an example of using a subroutine in an ASP.NET web page, as well as an example using a function. However, one thing that we have been using in virtually all of our ASP.NET page examples throughout this entire book is an event handler. You may be wondering where, exactly, event handlers fit into the picture of subroutines and functions. To understand, let's first look at the form of the Page_Load event handler in the following code:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load   ... End Sub 


As you can tell by the syntax of the Page_Load event handler, an event handler is a subroutine. Event handlers were designed as subroutines because event handlers never return a value. In addition, the event handlers we have looked at thus farthe Page_Load event handler and the Click event handler for Button Web controlsaccept two parameters: the first of type Object and the second of type EventArgs. The details of these parameters are unimportant for now; in later hours we'll examine their meaning in more depth.

Finally, note that an event handler's subroutine definition ends with Handles object.Event. object.Event is the event that is associated with this event handler. That is, when the specified event fires, the event handler will execute. It's the Handles keyword that wires up the specified event to this event handler.

The important information to grasp here is that an event handler is a subroutine. An event handler provides a modularized chunk of code that is executed whenever its corresponding event fires, and that corresponding event is spelled out in the Handles clause.




Sams Teach Yourself ASP. NET 2.0 in 24 Hours, Complete Starter Kit
Sams Teach Yourself ASP.NET 2.0 in 24 Hours, Complete Starter Kit
ISBN: 0672327384
EAN: 2147483647
Year: 2004
Pages: 233

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