DECISION STATEMENTS

A decision or conditional statement represents a branch in the program. It marks a place where the program can execute one set of statements or another, or possibly no statements at all, depending on some condition. These include several kinds of If statements, Choose statements, and Select Case statements.

Single-Line If Then

The single-line If Then statement has two basic forms. The first allows the program to execute a single statement if some condition is True. The syntax is as follows:

If condition Then statement

If the condition is True, the program executes the statement. In the most common form of single-line If Then statements, the statement is a single simple command (such as assigning a value to a variable or calling a subroutine).

The following example checks the emp object’s IsManager property. If IsManager is True, the statement sets the emp object’s Salary property to 90,000.

If emp.IsManager Then emp.Salary = 90000

The second form of the single-line If Then statement uses the Else keyword. The syntax is as follows:

If condition Then statement1 Else statement2

If the condition is True, the code executes the first statement. If the condition is False, the code executes the second statement. The decision about which statement to execute is an either-or decision; the code executes one statement or the other, but not both.

This type of single-line If Then Else statement can be confusing if it is too long to easily see in the code editor. For longer statements, a multiline If Then Else statement is easier to understand and debug. The performance of single-line and multiline If Then Else statements is comparable (in one test, the multiline version took only about 80 percent as long), so you should use the one that is easiest for you to read.

The single-line If Then statement can also include Else If clauses. For example, the following code examines the variable X. If X is 1, the program sets variable txt to “One.” If X has the value 2, the program sets txt to “Two.” If X is not 1 or 2, the program sets txt to a question mark.

Dim txt As String
If X = 1 Then txt = "One" Else If X = 2 Then txt = "Two" Else txt = "?"

The code can include as many Else If clauses as you like. However, confusing code such as the preceding example can lead to puzzling bugs that are easy to avoid if you use multiline If Then statements instead.

In summary, if you can write a simple single-line If Then statement with no Else If or Else clauses, and the whole thing fits nicely on the line so that it’s easy to see the whole thing without confusion, go ahead. If the statement is too long to read easily, or contains Else If or Else clauses, you are usually better off using a multiline If Then statement. It may take more lines of code, but the code will be easier to read, debug, and maintain later.

Multiline If Then

A multiline If Then statement can execute more than one line of code when a condition is True. The syntax for the simplest form of the multiline If Then statement is as follows:

If condition Then
    statements ... 
End If

If the condition is True, the program executes all the commands that come before the End If statement.

Like the single-line If Then statement, the multiline version can include Else If and Else clauses. For possibly historical reasons, ElseIf is spelled as a single word in the multiline If Then statement. The syntax is as follows:

If condition1 Then
    statements1 ... 
ElseIf condition2
    statements2 ... 
Else
    statements3 ... 
End If

If the first condition is True, the program executes the first set of statements. If the first condition is False, the code examines the second condition and, if that one is True, the code executes the second set of statements. The program continues checking conditions until it finds one that is True and it executes the corresponding code.

If the program reaches an Else statement, it executes the corresponding code. If the program reaches the End If statement without finding a True condition or an Else clause, it doesn’t execute any of the statement blocks.

It is important to understand that the program exits the If Then construction immediately after it has executed any block of statements. It does not examine the other conditions. This saves the program some time and is particularly important if the conditions involve functions. If each test calls a relatively slow function, skipping these later tests can save the program a significant amount of time.

Select Case

The Select Case statement lets a program execute one of several pieces of code depending on a single value. The basic syntax is as follows:

Select Case test_value
    Case comparison_expression1
        statements1
    Case comparison_expression2
        statements2
    Case comparison_expression3
        statements3
    ... 
    Case Else
        else_statements
End Select

If test_value matches comparison_expression1, the program executes the statements in the block statements1. If test_value matches comparison_expression2, the program executes the statements in the block statements2. The program continues checking the expressions in the Case statements in order until it matches one, or it runs out of Case statements.

If test_value doesn’t match any of the expressions in the Case statements, the program executes the code in the else_statements block. Note that you can omit the Case Else section. In that case, the program executes no code if test_value doesn’t match any of the expressions.

Select Case is functionally equivalent to an If Then Else statement. The following code does the same thing as the previous Select Case code:

If test_value = comparison_expression1 Then
    statements1
ElseIf test_value = comparison_expression2 Then
    statements2
ElseIf test_value = comparison_expression3 Then
    statements3
... 
Else
    else_statements
End If

Select Case is sometimes easier to understand than a long If Then Else statement. It is often faster as well, largely because Select Case doesn’t need to reevaluate test_value for every Case statement. If test_value is a simple variable, the difference is insignificant, but if test_value represents a slow function call, the difference can be important. For example, suppose test_value represents a function that opens a database and looks up a value. The Select Case version will find the value once and use it in each comparison, whereas the If Then version would reopen the database for each comparison.

The previous If Then example assumes the comparison expressions are constants. A comparison expression can also specify ranges using the To and Is keywords, and include a comma-separated list of expressions. These forms are described in the following sections.

To

The To keyword specifies a range of values that test_value should match. The following code examines the variable num_items. If num_items is between 1 and 10, the program calls subroutine ProcessSmallOrder. If num_items is between 11 and 100, the program calls subroutine ProcessLargeOrder. If num_items is less than 1 or greater than 100, the program beeps.

Select Case num_items
    Case 1 To 10
        ProcessSmallOrder()
    Case 11 To 100
        ProcessLargeOrder()
    Case Else
        Beep()
End Select

Is

The Is keyword lets you perform logical comparisons using the test value. The word Is takes the place of the test value in the comparison expression. For example, the following code does almost the same things as the previous code. If the value num_items is less than or equal to 10, the program calls subroutine ProcessSmallOrder. If the first Case clause doesn’t apply and num_items is less than or equal to 100, the program calls subroutine ProcessLargeOrder. If neither of these cases applies, the program beeps.

Select Case num_items
    Case Is <= 10
        ProcessSmallOrder()
    Case Is <= 100
        ProcessLargeOrder()
    Case Else
        Beep()
End Select

This version is slightly different from the previous one. If num_items is less than 1, this code calls subroutine ProcessSmallOrder whereas the previous version beeps.

You can use the operators =, <>, <, <=, >, and >= in an Is clause. (In fact, when you use a simple value in a Case clause as in Case 7, you are implicitly using Is = as in Case Is = 7.)

Comma-Separated Expressions

A comparison expression can include a series of expressions separated by commas. If the test value matches any of the comparison values, the program executes the corresponding code.

For example, the following code examines the department_name variable. If department_name is “R & D,” “Test,” or “Computer Operations,” the code adds the text “Building 10” to the address_text string. If department_name is “Finance,” “Purchasing,” or “Accounting,” the code adds “Building 7” to the address. More Case clauses could check for other department_name values and the code could include an Else statement.

Select Case department_name
    Case "R & D", "Test", "Computer Operations"
        address_text &= "Building 10"
    Case "Finance", "Purchasing", "Accounting"
        address_text &= "Building 7"
    ... 
End Select

Note that you cannot use comma-separated expressions in a Case Else clause. For example, the following code doesn’t work:

Case Else, "Corporate" ' This doesn't work.

You can mix and match constants, To, and Is expressions in a single Case clause, as shown in the following example. This code checks the variable item_code and calls subroutine DoSomething if the value is less than 10, between 30 and 40 inclusive, exactly equal to 100, or greater than 200.

Select Case item_code
    Case Is < 10, 30 To 40, 100, Is > 200
        DoSomething()
    ... 
End Select

Enumerated Values

Select Case statements work very naturally with lists of discrete values. You can have a separate Case statement for each value, or you can list multiple values for one Case statement in a comma-separated list.

Enumerated types defined by the Enum statement also work with discrete values, so they work well with Select Case statements. The enumerated type defines the values and the Select Case statement uses them, as shown in the following code fragment:

Private Enum JobStates
    Pending
    Assigned
    InProgress
    ReadyToTest
    Tested
    Released
End Enum
Private m_JobState As JobStates
...
Select Case m_JobState
    Case Pending
        ...
    Case Assigned
        ...
    Case InProgress
        ...
    Case ReadyToTest
        ...
    Case Tested
        ...
    Case Released
        ...
End Select

To catch bugs when changing an enumerated type, many developers include a Case Else statement that throws an exception. If you later add a new value to the enumerated type but forget to add corresponding code to the Select Case statement, the Select Case statement throws an error when it sees the new value, so you can fix the code.

For more information on enumerated types, see the section “Enumerated Data Types” in Chapter 14, “Data Types, Variables, and Constants.”

IIf

The IIf statement evaluates a Boolean expression and then returns one of two values, depending on whether the expression is True or False. This statement may look more like an assignment statement or a function call than a decision statement such as If Then.

The syntax is as follows:

variable = IIf(condition, value_if_true, value_if_false)

For example, the following code examines an Employee object’s IsManager property. If IsManager is True, the code sets the employee’s Salary to 90,000. If IsManager is False, the code sets the employee’s Salary to 10,000.

emp.Salary = IIf(emp.IsManager, 90000, 10000)

Note that the IIf statement returns an Object data type. If you have Option Strict turned on, Visual Basic will not allow this statement, because it assigns a result of type Object to an Integer variable. To satisfy Visual Basic, you must explicitly convert the value into an Integer, as in the following code:

emp.Salary = CInt(IIf(emp.IsManager, 90000, 10000))

The IIf statement has several drawbacks. First, it is confusing. When you type an IIf statement, IntelliSense will remind you that its parameters give a condition, a True value, and a False value. When you are reading the code, however, you must remember what the different parts of the statement mean. If you use IIf in some other statement, the chances for confusion increase. For example, consider the following code:

For i = 1 To CInt(IIf(employees_loaded, num_employees, 0))
    ' Process employee i.
    ... 
Next i

Code is generally much easier to understand if you replace IIf with an appropriate If Then statement.

Another drawback to IIf is that it evaluates both the True and False values whether the condition is True or False. For example, consider the following code:

num_objects = CInt(IIf(use_groups, CountGroups(), CountIndividuals()))

If the Boolean use_groups is True, this code sets num_objects to the result of the CountGroups function. If use_groups is False, the code sets num_objects to the result of the CountIndividuals function. In either case, IIf evaluates both functions no matter which value it actually needs. If the functions are time-consuming or executed inside a large loop, using IIf can waste a lot of time.

For an even more dangerous example, consider the following code:

num_loaded = CInt(IIf(data_loaded, num_employees, LoadEmployees()))

If data_loaded is True, this statement sets num_loaded = num_employees. If data_loaded is False, the code sets num_loaded to the value returned by the LoadEmployees function (which loads the employees and returns the number of employees it loaded).

IIf evaluates both the value num_employees and the value LoadEmployees() no matter what. If the employees are already loaded, IIf calls LoadEmployees() to load the employees again, ignores the returned result, and sets num_loaded = num_employees. LoadEmployees may waste quite a lot of time loading the data that is already loaded. Even worse, the program may not be able to handle loading the data when it is already loaded.

A final drawback to IIf is that it is slower than a comparable If Then Else statement. In one test, IIf took roughly twice as long as a comparable If Then statement.

One case where you can argue that IIf is easier to understand is when you have a long series of very simple statements. In that case, IIf statements may allow you to easily see the common features in the code and notice if anything looks wrong. For example, the following code initializes several text boxes using strings. It uses an IIf statement to set a text box’s value to <Missing> if the string is not yet initialized.

txtLastName.Text = IIf(last_name Is Nothing, "<Missing>", last_name)
txtFirstName.Text = IIf(first_name Is Nothing, "<Missing>", first_name)
txtStreet.Text = IIf(street Is Nothing, "<Missing>", street)
txtCity.Text = IIf(city Is Nothing, "<Missing>", city)
txtState.Text = IIf(state Is Nothing, "<Missing>", state)
txtZip.Text = IIf(zip Is Nothing, "<Missing>", zip)

To avoid confusing side effects, use IIf only if it makes the code easier to understand.

If

The If statement, not to be confused with an If Then statement, resolves some of the problems with the IIf statement. It evaluates a Boolean expression and then returns one of two values, depending on whether the expression is True or False, as IIf does. The difference is that If only evaluates the return value that it actually returns.

For example, the following code examines an Employee object’s IsManager property. If IsManager is True, the code sets the employee’s Salary to the result returned by the GetManagerSalary function and never calls function GetEmployeeSalary. If IsManager is False, the code sets the employee’s Salary to the result of the GetEmployeeSalary function and never calls function GetManagerSalary.

emp.Salary = If(emp.IsManager, GetManagerSalary(), GetEmployeeSalary())

Other than the fact that If doesn’t evaluate both of its possible return values, it behaves just as IIf does.

Choose

The IIf and If statements use a Boolean expression to pick between two values. The Choose statement uses an integer to decide among any number of options. The syntax is as follows:

variable = Choose(index, value1, value2, value3, value4, ... )

If the index parameter is 1, Choose returns the first value, value1; if index is 2, Choose returns value2; and so forth. If index is less than 1 or greater than the number of values in the parameter list, Choose returns Nothing.

This statement has the same drawbacks as IIf. Choose evaluates all of the result values no matter which one is selected, so it can slow performance. It can be particularly confusing if the values are functions with side effects.

Often Choose is more confusing than a comparable Select Case statement. If the values look dissimilar (mixing integers, objects, function calls, and so forth), involve complicated functions, or are wrapped across multiple lines, a Select Case statement may be easier to read.

However, if the Choose statement’s values are short and easy to understand, and the statement contains many values, the Choose statement may be easier to read. For example, the following Choose and Select Case statements do the same thing. Because the Choose statement’s values are short and easy to understand, this statement is easy to read. The Select Case statement is rather long. If the program had more choices, the Select Case statement would be even longer, making it more difficult to read.

fruit = Choose(index, "apple", "banana", "cherry", "date")
 
Select Case index
    Case 1
        fruit = "apple"
    Case 2
        fruit = "banana"
    Case 3
        fruit = "cherry"
    Case 4
        fruit = "date"
End Select

Although it’s not always clear whether a Choose statement or a Select Case statement will be easier to read, Select Case is certainly faster. In one test, Choose took more than five times as long as Select Case. If the code lies inside a frequently executed loop, the speed difference may be an issue.

Choose and Select Case are not your only options. You can also store the program’s choices in an array, and then use the index to pick an item from the array. For example, the following code stores the strings from the previous example in the values array. It then uses the index to pick the right choice from the array.

Dim fruit_names() As String = {"apple", "banana", "cherry", "date"}
 
fruit = fruit_names(index - 1)

INTELLIGENT INDEXING
Notice that the code subtracts 1 from the index when using it to pick the right choice. The Choose statement indexes its values starting with 1, but arrays in Visual Basic .NET start with index 0. Subtracting 1 allows the program to use the same index values used in the previous example.

This version makes you think about the code in a different way. It requires that you know that the fruit_names array contains the names of the fruits that the program needs. If you understand the array’s purpose, then the assignment statement is easy to understand.

The assignment code is even slightly faster than Select Case, at least if you can initialize the fruit_names array ahead of time.

If you find Choose easy to understand and it doesn’t make your code more difficult to read in your particular circumstances, by all means use it. If Select Case seems clearer, use that. If you will need to perform the assignment many times and pre-building an array of values makes sense, using a value array might improve your performance.

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

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