按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
Missing from the TestCallingExample() method is an indication of whether the processing
worked。 It is assumed from the perspective of the caller of TestCallingExample() that
calling TestCallingExample() will always result in something being done。 The caller of
TestCallingExample() has no way of knowing that something failed; other than if an exception
was thrown。
Code that tells you if something went wrong using an exception is both a blessing and a
curse。 It is a blessing because the code is telling you that something went wrong。 But it is a
curse because sometimes you know something could go wrong; and that it is OK; but you don’t
want the exception to travel up the program hierarchy。 In these cases; you need to catch the
exception; which makes your code more plicated。
For example; say you wanted to parse a number。 The parsing routines tend to give a
result if everything worked OK; but generate an exception if things are not OK。 There is no
return value; just an exception。 But when parsing a number; you do know that things could go
wrong; so you will need to write an exception handler。 Following is some source code that
parses a number。
Function TestGetValue(ByVal buffer As String) As Integer
Dim retval As Integer = 0
Try
retval = Integer。Parse(buffer)
Catch ex As FormatException
Console。WriteLine(〃Exception (〃 & ex。Message & 〃)〃)
End Try
Return retval
End Function
In the example; the code realizes that if Parse() is called and the string cannot be converted
into a number due to incorrect letters or numbers; an exception will be thrown。 The exception
will be caught; processed (using the exception’s Message property to obtain the problem); and
then the value of retval will be returned to the caller。 But what if an exception does happen?
The variable retval is initialized to a default value of 0; which is a valid formatted number and
can be interpreted as the result of a successful format processing。
…………………………………………………………Page 153……………………………………………………………
CH AP T E R 5 ■ L E AR N IN G AB O U T V I SU A L B AS IC E X CE PT I ON HA N D L IN G 131
The problem in the code is that a developer is caught in a bind。 By capturing the exception;
the method TestGetValue() is saying; “I will always return to the caller a valid value。” Yet there
are instances when a valid value is not available。 In the case of parsing a number; an exception
is thrown。 So by capturing an exception; you are doing the pletely wrong thing; because
you should be letting the exception be caught by a higher…level caller。 But things can bee
sticky here。 Do you really want to inform the caller that a parse cannot occur? Perhaps the caller
is more interested in whether a valid value is returned。 It’s like saying to the CEO; “Oops; we
just ran out of staples。” Sure; staples might be important; and maybe the pany will not run
as smoothly; but do you really want to inform the CEO about every little problem?
Microsoft developers know about this problem with parsing; and use an approach that
you can use as well。 As you learned in Chapter 3; there are two variations of parsing a number:
o Parse() returns a valid number if the buffer could be parsed; and an exception if a
number could not be parsed。
o TryParse() returns a True or False value indicating the result of the parse。
Here’s how you could rewrite the TestGetValue() method to use TryParse():
Function TestGetValue(ByVal buffer As String; ByRef val As Integer) As Boolean
Dim retval As Boolean = False
If Integer。TryParse(buffer; val) Then
retval = True
End If
Return retval
End Function
In the modified example; TestGetValue() returns a True or False to indicate a success or
failure when parsing a number。 If a True is returned; the parameter val will hold a valid number;
otherwise; val should be not be used。
Some of you might have caught that my use of Parse() and TryParse() is not very creative。
The method TestGetValue() could have been reduced to a single line:
Function TestGetValue(ByVal buffer As String; ByRef val As Integer) As Boolean
Return Integer。TryParse(buffer; val)
End Function
Using Default State
Default state is a useful technique to guard against exceptions that developers often ignore。
When developers are writing their code; they will often return Nothing when things don’t work
out。 Using Nothing is not a bad idea; but it adds unnecessary baggage。 For example; consider
the following code:
Class DefaultStateWrong
Private Function Tokenize(ByVal buffer As String) As String()
Return Nothing
End Function
…………………………………………………………Page 154……………………………………………………………
132 CH AP T E R 5 ■ L E A R N IN G AB OU T V I SU A L B AS IC E X C E P TI ON H AN D L IN G
Public Sub IterateBuffers(ByVal buffer As String)
Dim found As String() = Tokenize(buffer)
If found IsNot Nothing Then
For c1 As Integer = 0 To found。Length 1
Console。WriteLine(〃Found (〃 & found(c1) & 〃)〃)
Next
End If
End Sub
End Class
The problem in this example is Tokenize(); which is a method used to convert the param
eter buffer into a series of string tokens。 Using safe exception coding; if the data could not be
parsed; y