Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
(ebook) Visual Studio .NET Mastering Visual Basic.pdf
Скачиваний:
120
Добавлен:
17.08.2013
Размер:
15.38 Mб
Скачать

ARGUMENTS 177

The function’s return type is Double(), meaning the function will return an array of doubles; that’s what the empty parentheses signify. This array is declared in the function’s body with the statement:

Dim Result(3) As Double

The function performs its calculations and then assigns the values of the basic statistics to the elements of the array Result. The first element holds the average, the second element holds the standard deviation, and the other two elements hold the minimum and maximum data values. The Result array is finally returned to the calling procedure by the statement that assigns the array to the function name, just as you’d assign a variable to the name of the function that returns a single result.

The code behind the Calculate Statistics button, which calls the ArrayStats() function, is shown in Listing 4.3.

Listing 4.3: Calculating Statistics with the ArrayStats() Function

Protected Sub Button2_Click(ByVal sender As Object, _ ByVal e As System.EventArgs)

Dim SData(99) As Double Dim Stats() As Double Dim i As Integer

Dim rnd As New System.Random() ListBox1.Items.Clear()

For i = 0 To 99

SData(i) = rnd.NextDouble() * 1000 ListBox1.Items.Add(SData(i))

Next

Stats = ArrayStats(SData)

TextBox1.Text = “Average” & vbTab & vbTab & Stats(0)

TextBox1.Text = TextBox1.Text & cvCrLf & “Std. Deviation” & vbTab & Stats(1) TextBox1.Text = TextBox1.Text & vbCrLf & “Min. Value” & vbTab & Stats(2) TextBox1.Text = TextBox1.Text & vbCrLf & “Max. Value” & vbTab & Stats(3)

End Sub

The code generates 100 random values and displays them on a ListBox control. Then, it calls the ArrayStats() function, passing the data values to it through the SData array. The function’s return values are stored in the Stats array, which is declared as double but without dimensions. Then, the code displays the basic statistics on a TextBox control, one item per line.

Overloading Functions

There are situations where the same function must operate on different data types, or a different number of arguments. In the past, you had to write different functions, with different names and different arguments, to accommodate similar requirements. VB.NET introduces the concept of function overloading, which means that you can have multiple implementations of the same function, each with a different set of arguments and, possibly, a different return value. Yet, all overloaded functions share the same name. Let me introduce this concept by examining one of the many overloaded functions that come with the .NET Framework.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

178 Chapter 4 WRITING AND USING PROCEDURES

To generate a random number in the range from 0 to 1 (exclusive), use the NextDouble method of the System.Random class. To use the methods of the Random class, you must first create an instance of the class and then call the methods:

Dim rnd As New System.Random Console.WriteLine(“Three random numbers”)

Console.Write(rnd.NextDouble() & “ – “ & rnd.NextDouble() & “ – “ & _ rnd.NextDouble())

The random numbers that will be printed on the Output window will be double precision values in the range 0 to 1:

0.656691639058614 – 0.967485965680092 – 0.993525570721145

More often than not, we need integer random values. The Next method of the System.Random class returns an integer value from –2,147,483,648 to 2,147,483,647 (this is the range of values that can be represented by the Integer data type). We also want to generate random numbers in a limited range of integer values. To emulate the throw of a dice, we want a random value in the range from 1 to 6, while for a roulette game we want an integer random value in the range from 0 to 36. You can specify an upper limit for the random number with an optional integer argument. The following statement will return a random integer in the range from 0 to 99:

randomInt = rnd.Next(100)

Finally, you can specify both the lower and upper limits of the random number’s range. The following statement will return a random integer in the range from 1,000 to 1,999:

randomInt = rnd.Next(1000, 2000)

The same method behaves differently based on the arguments we supply. The behavior of the method depends either on the type of the arguments, the number of the arguments, or both of them. As you will see, there’s no single function that alters its behavior based on its arguments. There are as many different implementations of the same function as there are argument combinations. All the functions share the same name, so that they appear to the user as a single, multifaceted function. These functions are overloaded, and you’ll see in the following section how they’re implemented.

If you haven’t turned off the IntelliSense feature of the editor, then as soon as you type the opening parenthesis after a function or method name, you see a yellow box with the syntax of the function or method. You’ll know that a function is overloaded when this box contains a number and two arrows. Each number corresponds to a different overloaded form, and you can move to the next or previous overloaded form by clicking the two little arrows or by pressing the arrow keys.

Let’s return to the Min() function we implemented earlier in this chapter. The initial implementation of the Min() function is shown next:

Function Min(ByVal a As Double, ByVal b As Double) As Double

Min = IIf(a < b, a, b)

End Function

By accepting double values as arguments, this function can handle all numeric types. VB.NET performs automatically widening conversions (it can convert integers and decimals to doubles), so this trick makes our function work with all numeric data types. However, what about strings? If you

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

ARGUMENTS 179

attempt to call the Min() function with two strings as arguments, you’ll get an exception. The Min() function just can’t handle strings.

To write a Min() function that can handle both numeric and string values, you must, in essence, write two Min() functions. All Min() functions must be prefixed with the Overloads keyword. The following statements show two different implementations of the same function:

Overloads Function Min(ByVal a As Double, ByVal b As Double) As Double Min = IIf(a < b, a, b)

End Function

Overloads Function Min(ByVal a As String, ByVal b As String) As String Min = IIf(a < b, a, b)

End Function

As you may have guessed, we need a third overloaded form of the same function to compare dates. If you call the Min() function with two dates are arguments, as in the following statement, the Min() function will compare them as strings.

Console.WriteLine(Min(#1/1/2001#, #3/4/2000#))

This statement will print the date 1/1/2001, which is not the smaller (earlier) date. If you swap the years and call the function as

Console.WriteLine(Min(#1/1/2000#, #3/4/2001#))

you’ll get the earlier date, but just because it happens that their alphanumeric order is now the same as their chronological order.

The overloaded form of the function that accepts dates as arguments is shown next:

Overloads Function Min(ByVal a As Date, ByVal b As Date) As Date

Min = IIf(a < b, a, b)

End Function

If you now call the Min() function with the dates #1/1/2001# and #3/4/2000#, the function will return the second date, which is chronologically smaller than the first.

OK, the example of the Min() function is rather trivial. You can also write a Min() function that compares two objects and handle all other data types. Let’s look into a more complicated overloaded function, which makes use of some topics discussed later in this book. The CountFiles() function counts the number of files that meet certain criteria. The criteria could be the size of the files, their type, or the date they were created. You can come up with any combination of these criteria, but here are the most useful combinations. (These are the functions I would use, but you can create even more combinations, or introduce new criteria of your own.) The names of the arguments are selfdescriptive, so I need not explain what each form of the CountFiles() function does.

CountFiles(ByVal minSize As Integer, ByVal maxSize As Integer) As Integer CountFiles(ByVal fromDate As Date, ByVal toDate As Date) As Integer CountFiles(ByVal type As String) As Integer

CountFiles(ByVal minSize As Integer, ByVal maxSize As Integer, _ ByVal type As String) As Integer

CountFiles(ByVal fromDate As Date, ByVal toDate As Date, _ ByVal type As String) As Integer

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

180 Chapter 4 WRITING AND USING PROCEDURES

Listing 4.4 shows the implementation of these overloaded forms of the CountFiles() function. Since we haven’t discussed files yet, most of the code in the function’s body will be new to you—but it’s not hard to follow. For the benefit of readers who are totally unfamiliar with file operations, I’ve included a statement that prints on the Output window the type of files counted by each function. The Console.WriteLine statement prints the values of the arguments passed to the function, along with a description of the type of search it’s going to perform. The overloaded form that accepts two integer values as arguments prints something like:

You’ve requested the files between 1000 and 100000 bytes

while the overloaded form that accepts a string as argument prints the following:

You’ve requested the .EXE files

Listing 4.4: The Overloaded Implementations of the CountFiles() Function

Overloads Function CountFiles(ByVal minSize As Integer, _

ByVal maxSize As Integer) As Integer Console.WriteLine(“You’ve requested the files between “ & minSize & _

“ and “ & maxSize & “ bytes”) Dim files() As String

files = System.IO.Directory.GetFiles(“c:\windows”) Dim i, fileCount As Integer

For i = 0 To files.GetUpperBound(0)

Dim FI As New System.IO.FileInfo(files(i))

If FI.Length >= minSize And FI.Length <= maxSize Then fileCount = fileCount + 1

End If Next

Return(fileCount) End Function

Overloads Function CountFiles(ByVal fromDate As Date, _

ByVal toDate As Date) As Integer Console.WriteLine(“You’ve requested the count of files created from “ & _

fromDate & “ to “ & toDate) Dim files() As String

files = System.IO.Directory.GetFiles(“c:\windows”) Dim i, fileCount As Integer

For i = 0 To files.GetUpperBound(0)

Dim FI As New System.IO.FileInfo(files(i)) If FI.CreationTime.Date >= fromDate And _ FI.CreationTime.Date <= toDate Then

fileCount = fileCount + 1 End If

Next Return(fileCount)

End Function

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

ARGUMENTS 181

Overloads Function CountFiles(ByVal type As String) As Integer Console.WriteLine(“You’ve requested the “ & type & “ files”) Dim files() As String

files = System.IO.Directory.GetFiles(“c:\windows”) Dim i, fileCount As Integer

For i = 0 To files.GetUpperBound(0)

Dim FI As New System.IO.FileInfo(files(i)) If FI.Extension = type Then

fileCount = fileCount + 1 End If

Next Return(fileCount)

End Function

Overloads Function CountFiles(ByVal minSize As Integer, _

ByVal maxSize As Integer, ByVal type As String) As Integer Console.WriteLine(“You’ve requested the “ & type & “ files between “ & _

minSize & “ and “ & maxSize & “ bytes”) Dim files() As String

files = System.IO.Directory.GetFiles(“c:\windows”) Dim i, fileCount As Integer

For i = 0 To files.GetUpperBound(0)

Dim FI As New System.IO.FileInfo(files(i)) If FI.Length >= minSize And _

FI.Length <= maxSize And _ FI.Extension = type Then

fileCount = fileCount + 1 End If

Next Return(fileCount)

End Function

Overloads Function CountFiles(ByVal fromDate As Date, ByVal toDate As Date, _ ByVal type As String) As Integer

Console.WriteLine(“You’ve requested the “ & type & _

“ files created from “ & fromDate & “ to “ & toDate) Dim files() As String

files = System.IO.Directory.GetFiles(“c:\windows”) Dim i, fileCount As Integer

For i = 0 To files.GetUpperBound(0)

Dim FI As New System.IO.FileInfo(files(i)) If FI.CreationTime.Date >= fromDate And _

FI.CreationTime.Date <= toDate And FI.Extension = type Then fileCount = fileCount + 1

End If Next

Return(fileCount) End Function

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

182 Chapter 4 WRITING AND USING PROCEDURES

If you’re unfamiliar with the Directory and File objects, focus on the statement that prints to the Output window and ignore the statements that actually count the files that meet the specified criteria. After reading Chapter 13, you can revisit this example and understand the counting statements. The Console.WriteLine statements report all the values passed as arguments, and they differentiate between the various overloaded forms of the function.

Start a new project and enter the definitions of the overloaded forms of the function on the form’s level. Listing 4.4 is lengthy, but all the overloaded functions have the same structure and differ only in how they select the files to count. Then place a TextBox and a button on the form, as shown in Figure 4.4, and enter the statements from Listing 4.5 in the button’s Click event handler. The project shown in Figure 4.4 is called OverloadedFunctions, and you’ll find it in this chapter’s folder on the CD.

Figure 4.4

The Overloaded-

Functions project

Listing 4.5: Testing the Overloaded Forms of the CountFiles() Function

Private Sub Button1_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles Button1.Click TextBox1.AppendText(CountFiles(1000, 100000) & _

“ files with size between 1KB and 100KB” & vbCrLf) TextBox1.AppendText(CountFiles(#1/1/2001#, #12/31/2001#) & _

“ files created in 2001” & vbCrLf) TextBox1.AppendText(CountFiles(“.BMP”) & “ BMP files” & vbCrLf) TextBox1.AppendText(CountFiles(1000, 100000, “.EXE”) & _

“ EXE files between 1 and 100 KB” & vbCrLf) TextBox1.AppendText(CountFiles(#1/1/2000#, #12/31/2001#, “.EXE”) & _

“ EXE files created in 2000 and 2001”)

End Sub

The button calls the various overloaded forms of the CountFiles() function one after the other and prints the results on the TextBox control.

Function overloading is new to VB.NET, but it’s used heavily throughout the language. There are relatively few functions (or methods, for that matter) that aren’t overloaded. Every time you enter the name of a function followed by an opening parenthesis, a list of its arguments appears in the drop-down list with the arguments of the function. If the function is overloaded, you’ll see a

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com