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

VARIABLES 107

subtle errors, and they avoid it. It’s up to you to decide whether to use variants and how far you will go with them. Sure, you can perform tricks with variants, but you shouldn’t overuse them to the point that others can’t read your code.

You can also store dates and times in an Object variable. To assign a date or time value to a variant, surround the value with pound signs, as follows:

date1 = #03/06/1999#

All operations that you can perform on date variables (discussed in the section “Date Variables”) you can also perform with variants, which hold date and time values.

Converting Variable Types

In some situations, you will need to convert variables from one type into another. Table 3.3 shows the Visual Basic functions that perform data-type conversions. Actually, you will have to convert between data types quite often now that VB doesn’t do it for you.

Table 3.3: Data-Type Conversion Functions

Function

Converts Its Argument To

CBool

Boolean

CByte

Byte

CChar

Unicode character

CDate

Date

CDbl

Double

CDec

Decimal

CInt

Integer (4-byte integer, Int32)

CLng

Long (8-byte integer, Int64)

CObj

Object

CShort

Short (2-byte integer, Int16)

CSng

Single

CStr

String

 

 

To convert the variable initialized as

Dim A As Integer

to a Double, use the function:

Dim B As Double

B = CDbl(A)

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

108 Chapter 3 VISUAL BASIC: THE LANGUAGE

Suppose you have declared two integers, as follows:

Dim A As Integer, B As Integer

A = 23

B = 7

The result of the operation A / B will be a double value. The following statement:

Console.Write(A / B)

displays the value 3.28571428571429. The result is a double, which provides the greatest possible accuracy. If you attempt to assign the result to a variable that hasn’t been declared as Double, and the Strict option is On, then VB.NET will generate an error message. No other data type can accept this value without loss of accuracy.

As a reminder, the Short data type is equivalent to the old Integer type, and the CShort() function converts its argument to an Int16 value. The Integer data type is represented by 4 bytes (32 bits), and to convert a value to Int32 type, use the CInt() function. Finally, the CLng() function converts its argument to an Int64 value.

You can also use the CType() function to convert a variable or expression from one type to another. Let’s say the variable A has been declared as String and holds the value “34.56”. The following statement converts the value of the A variable to a Decimal value and uses it in a calculation:

Dim A As String = “34.56”

Dim B As Double

B = CType(A, Double) / 1.14

The conversion is necessary only if the Strict option is On, but it’s a good practice to perform your conversions explicitly. The following section explains what may happen if your code relies to implicit conversions.

Widening and Narrowing Conversions

In some situations, VB.NET will convert data types automatically, but not always. Let’s say you have declared and initialized two variables, an integer and a double, with the following statements:

Dim count As Integer = 99

Dim pi As Double = 3.1415926535897931

If the Strict option is On and you attempt to assign the value of the pi variable to the count variable, the compiler will generate an error message to the effect that you can’t convert a double to an integer. The exact message is:

Option Strict disallows implicit conversions from Double to Integer

VB6 VB.NET

You will probably see this message many times, especially if you’re a VB6 programmer. In the past, VB would store the value 3 to the count variable and proceed. If you weren’t careful, you’d lose significant decimal digits and might not even know it. This implicit conversion results in loss of accuracy, and VB.NET doesn’t perform it by default. This is a typical example of the pitfalls of turning off the Strict option.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

VARIABLES 109

When the Strict option is On, VB.NET will perform conversions that do not result in loss of accuracy (precision) or magnitude. These conversions are called widening conversions, as opposed to the narrowing conversions. When you assign an Integer value to a Double variable, no accuracy or magnitude is lost. On the other hand, when you assign a double value to an integer variable, then some accuracy is lost (the decimal digits must be truncated). Since you, the programmer, are in control, you may wish to give up the accuracy—presumably, it’s no longer needed. When the Strict option is on, VB.NET doesn’t assume that you’re willing to sacrifice the accuracy, even if this is your intention. Instead, it forces you to convert the data type explicitly with one of the data type conversion functions. Normally, you must convert the Double value to an Integer value and then assign it to an Integer variable:

count = CInt(pi)

This is a narrowing conversion (from a value with greater accuracy or magnitude to a value with smaller accuracy or magnitude), and it’s not performed automatically by VB.NET. Table 3.4 summarizes the widening conversions VB.NET will perform for you automatically.

Table 3.4: VB.NET Widening Conversions

Original Data Type

Wider Data Type

Any type

Object

Byte

Short, Integer, Long, Decimal, Single, Double

Short

Integer, Long, Decimal, Single, Double

Integer

Long, Decimal, Single, Double

Long

Decimal, Single, Double

Decimal

Single, Double

Single

Double

Double

none

Char

String

 

 

In the first beta version of Visual Studio .NET, the Strict option was on by default. It seems that pressure from VB6 programmers forced the designers of Visual Studio to change the default setting of this option. I expect that the default settings of the Strict option will be turned on again in the future, and eventually you won’t be able to turn it off.

If the Strict option is off (the default value), the compiler will allow you to assign a Long variable to an Integer variable. Should the Long variable contain a value that exceeds the range of values of the Integer data type, then you’ll end up with a runtime error. Of course, you can avoid the runtime error with the appropriate error-handling code. If the Strict option is on, the compiler will point out all the statements that may cause similar runtime errors, and you can re-evaluate your choice of variable types. You can also turn on the Strict option temporarily to see the compiler’s warnings, then turn it off again.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

110 Chapter 3 VISUAL BASIC: THE LANGUAGE

User-Defined Data Types

In the previous sections, we assumed that applications create variables to store individual values. As a matter of fact, most programs store sets of data of different types. For example, a program for balancing your checkbook must store several pieces of information for each check: the check’s number, amount, date, and so on. All these pieces of information are necessary to process the checks, and ideally, they should be stored together.

A structure for storing multiple values (of the same or different type) is called a record. For example, each check in a checkbook-balancing application is stored in a separate record, as shown in Figure 3.2. When you recall a given check, you need all the information stored in the record.

Figure 3.2

Pictorial representation of a record

To define a record in VB.NET, use the Structure statement, which has the following syntax:

Structure structureName Dim variable1 As varType Dim variable2 As varType

...

Dim variablen As varType End Structure

varType can be any of the data types supported by the framework. The Dim statement can be replaced by the Private or Public access modifiers. For structures, Dim is equivalent to Public.

After this declaration, you have in essence created a new data type that you can use in your application. structureName can be used anywhere you’d use any of the base types (integers, doubles, and so on). You can declare variables of this type and manipulate them as you manipulate all other variables (with a little extra typing). The declaration for the record structure shown in Figure 3.2 is

Structure CheckRecord

Dim CheckNumber As Integer

Dim CheckDate As Date

Dim CheckAmount As Single

Dim CheckPaidTo As String

End Structure

This declaration must appear outside any procedure; you can’t declare a Structure in a subroutine or function. The CheckRecord structure is a new data type for your application. Depending on where the structure was declared, it may not be visible from the entire code, but it’s up to you to give your structure the proper scope (see the section “A Variable’s Scope,” later in this chapter for more information on variable scoping).

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

VARIABLES 111

To declare variables of this new type, use a statement such as this one:

Dim check1 As CheckRecord, check2 As CheckRecord

To assign a value to one of these variables, you must separately assign a value to each one of its components (they are called fields), which can be accessed by combining the name of the variable and the name of a field separated by a period, as follows:

check1.CheckNumber = 275

Actually, as soon as you type the period following the variable’s name, a list of all members to the CheckRecord structure will appear, as shown in Figure 3.3. Notice that the structure supports a few members on its own. You didn’t write any code for the Equals, GetType, and ToString members, but they’re standard members of any Structure object and you can use them in your code. Both the GetType and ToString methods will return a string like “ProjectName.FormName+CheckRecord”.

Figure 3.3

Variables of custom types expose their members as properties.

You can think of the record as an object and its fields as properties. Here are the assignment statements for a check:

check2.CheckNumber = 275 check2.CheckDate = #09/12/2001# check2.CheckAmount = 104.25 check2.CheckPaidTo = “Gas Co.”

You can also create arrays of records with a statement such as the following (arrays are discussed later in this chapter):

Dim Checks(100) As CheckRecord

Each element in this array is a CheckRecord record and holds all the fields of a given check. To access the fields of the third element of the array, use the following notation:

Checks(2).CheckNumber = 275

Checks(2).CheckDate = #09/12/2001#

Checks(2).CheckAmount = 104.25

Checks(2).CheckPaidTo = “Gas Co.”

All data types expose the Equals method, which compares an instance of a data type (a integer variable, for example) to another instance of the same type. This is a trivial operation for simple data

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

112 Chapter 3 VISUAL BASIC: THE LANGUAGE

types, as you can compare the two variables directly. The Equals method can also compare two Structure variables and return True if all of their fields match. If a single field differs, the two objects represented by the variables are not identical. Use this method to compare variables declared as custom structures to avoid comparing all their members. Let’s say you have created two variables of the CheckRecord type:

Dim c1, c2 As CheckRecord

{ assign values to the c1 and c2 variables } If c1.Equals(c2) Then

MsgBox “Same” Else

MsgBox “Different” End If

You can also use arrays as Structure members. The following structure uses an array to store multiple e-mail addresses for the same person:

Structure Person

Dim First As String

Dim Last As String

Dim Address As String

Dim Phone As String

Dim EMail(10) As String

End Structure

Using this structure, you can store up to 10 e-mail addresses per person. To use the Person structure in your code, declare a variable of this type:

Dim aPerson As Person

To access the first element of the EMail member, use the following notation:

aPerson.EMail(0) = “JDoe@tex.com”

You can also declare an array of Person structures, with the following statement:

Dim allPeople(1000) As Person

This array can hold contact information for 1,000 persons, and each person is identified by an index. That is, you must know the index corresponding to each person, or you must search the array to locate the person you’re interested in. In Chapter 11, you’ll learn how to index and search arrays with meaningful keys, like names, rather than indices.

To access an element of the EMail array, use two indices, one for the array of structures and

another one for the array member: allPeople(3).EMail(0), allPeople(3).EMail(1), and so on.

The Nothing Value

The Nothing value is used with Object variables and indicates a variable that has not been initialized. If you want to disassociate an Object variable from the object it represents, set it to Nothing. The following statements create an Object variable that references a Brush, use it, and then release it:

Dim brush As System.Drawing.Brush brush = New System.Drawing.Brush(bmap)

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com