Chapter 9: Learning Other Object-Oriented Programming Topics - Learn VB .NET Through Game Programming [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Learn VB .NET Through Game Programming [Electronic resources] - نسخه متنی

Matthew Tagliaferri

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
توضیحات
افزودن یادداشت جدید





Chapter 9: Learning Other Object-Oriented Programming Topics

This Chapter Covers a Few important Visual Basic .NET topics that don’t merit an entire chapter on their own but that represent some new features of the language and the underlying framework.


Understanding Structured Exception Handling


The sample projects that accompany this book contain numerous examples of structured exception handlers. This programming construct takes the form shown in Listing 9-1.

Listing 9.1: Exception Handling Syntax



Try
<code block>
[Catch [e as Exception]]
<exception handling block>
[Catch [e as Exception]]
<exception handling block>
[Finally]
<always-execute block>
End Try



An exception handler begins with a Try statement, followed by any number of statements. There may or may not be a Catch block. The Catch block, which may define a class of exception that it handles, runs if a runtime exception matching that class occurs in the previous Try block. The Finally block (also optional) is guaranteed to always run, regardless of any exceptions thrown or handled previously.


One caveat on the optional portions of an exception handler: Both the Catch clause and the Finally clause are optional, but the Try block must contain one or the other. For example, the following code block isn’t legal:


Try
<code block>
End Try

Not only is the previous code block illegal, it’s also useless because it doesn’t handle any exceptions that might occur within the code.

Exception handlers require a new way of error handling. The old-school Visual Basic programmer used to conceive of every possible error while developing the program and build tests into the code to handle every type of problem. Consider a program that writes a complicated data structure to disk (say a CAD program or a Doom level editor). Suppose that the code that writes the complicated data structure is several thousand lines of code. The process would be as follows: Open the file; write the header; write structure A; write substructure A1, A2, and A3; write structure B; write substructure A, B, and C; and so on. Now, consider all of the errors that might occur as this code runs:



Permission errors: It’s possible that the user would try to write a file to aread-only location, such as to a CD-ROM or an area of the network to which the user doesn’t have write access. Or, the user might attempt to overwrite a file that’s marked as read-only.



Media errors: Perhaps there’s a bad cluster on the destination media, and the write operation fails at some point.



Out of disk space errors: The media may run out of disk space as the file is being written.



These are only a few of the problems that might occur while writing. So, how might the Visual Basic programmer handle these problems? The first problem, checking for write access on the destination drive, isn’t too big of a problem. The program can write the header or a short portion of the file, check for any return codes or problems that might have occurred, and then stop the write operation at that point and exit the program cleanly.

The second and third problems are much more difficult to handle cleanly, however, because they could happen at any time during the data save operation. The save could get 5 percent through—or 50 percent or 95 percent—and then afailure could occur. Should the program be written in such a way that it checks after every write to disk that the write was successful? For example:



Write to disk
If WriteFailed then PrintErrorMessage, exit.
Write to disk
If WriteFailed then PrintErrorMessage, exit.
Write to disk
If WriteFailed then PrintErrorMessage, exit.

Ugh. Surely there’s a better way. The most common way Visual Basic 6 developers handled errors such as running out of disk space or write errors was to not handle them at all and hope they never occurred.

One of the primary powers of structured exception handling is that the program doesn’t have to check for errors after every line. Instead, the program designates that entire block of code should run, and if an exception happens on any of those lines, then execution jumps to the exception handler. Without focusing on exact .NET class names or file Input/Output (I/O) syntax, Listing 9-2 shows how you might write the complex data saver.

Listing 9.2: Pseudocode for the Complex Data Writing Routine



bError = false
Try
Open File for Write
Catch PermissionException
Print "Permission Error"
bError = true
Catch AnyOtherException
Print "Some other Error"
bError = true
End Try
If bError then exit sub
Try
Write Some Stuff
Write Some More Stuff
Write Still More Stuff
Write An Incredible Amount Of Stuff
Catch MediaFailException
Print "Bad Media"
Catch OutOfSpaceException
Print "Media Out Of Space"
Catch AnyOtherException
Print "Some other Error"
Finally
Close File
End Try



This code is about a zillion times cleaner because it handles the three potential errors identified earlier, and it does so regardless of how much more code you might add to the writing block. You can identify two exception handlers in this code. The first makes sure the file can be opened for writing. If a permission exception occurs, the user is told as such through some mechanism (identified only as Print in the pseudocode), and the routine exits. For even more robust error handling, this code includes a second exception handler that will catch all exceptions except the permission exceptions already caught by the previous block.

The second exception handler looks for the specific errors discussed earlier, plus it includes the catchall for anything you haven’t thought of to this point. It also contains a Finally block that makes 100-percent sure the file closes, no matter what errors may have occurred earlier.

I became grateful for one particular exception handler during the development of this book: the exception handler in the DirectDraw code for the dxSprite class discussed in Chapter 8, “Using DirectX.” By default, a DirectDraw program with an unhandled exception locks up the machine to a degree because the DirectDraw window doesn’t disappear to make way for Visual Studio to display any error that has occurred. Because of this, the best way to debug the drawing code is to place the DirectDraw code inside an exception handler and write any error that occurred to the Debug window. Listing 9-3 shows this exception handler.

Listing 9.3: Exception Handling in a DirectDraw World



Try
FWBB = Me.BoundingBox 'start w/ normal bbox
'start at the location
oPt = New Point(System.Math.Floor(Location.X), _
System.Math.Floor(Location.Y))
If oPt.X < 0 Then
'draw partial on left side
oRect = New Rectangle(oRect.Left - oPt.X, oRect.Top, _
oRect.Width + oPt.X, oRect.Height)
If oPt.X + FWBB.Left < 0 Then
FWBB = New Rectangle(0, FWBB.Top, _
FWBB.Width + (oPt.X + FWBB.Left), FWBB.Height)
Else
FWBB = New Rectangle(FWBB.Left + oPt.X, FWBB.Top, _
FWBB.Width, FWBB.Height)
End If
oPt.X = 0
End If
<lots of range checking code removed>
'should never happen, just in case
If oRect.Width <= 0 Or oRect.Height <= 0 Then Return
'offset the bounding box by the world coordinates
FWBB.Offset(oPt.X, oPt.Y)
'draw the sprite
oSurf.DrawFast(oPt.X, oPt.Y, oSource, oRect, _
DrawFastFlags.DoNotWait Or DrawFastFlags.SourceColorKey)
'draw the bounding box
If Me.pShowBoundingBox Then
oSurf.ForeColor = Color.Red
oSurf.DrawBox(FWBB.Left, FWBB.Top, FWBB.Right, FWBB.Bottom)
End If
Catch oEx As Exception
Debug.WriteLine("--------------------------------------")
Debug.WriteLine(oEx.Message)
End Try



/ 106