- Introducing the Framework Class Library (FCL) to Visual Basic Developers
- Programming with the Framework Class Library
Programming with the Framework Class Library
Because the Framework Class Library contains classes in the true object-oriented spirit of that word, there are two primary ways that you will find yourself using these base classes: as black boxes that you can call into, and as classes that you can inherit from and extend to craft your own functionality.
Instantiating Objects from the Class Library
The use of base classes as a black box is probably the primary path for most developers; in this mode, your code will be treating the class library as a simple API to get at core, base functions on your particular operating system.
Using the class library classes in this manner does not represent a departure from the programming model that Visual Basic developers are used to. As an example, if you have programmed Visual Basic applications that have made use of the ADO library, you probably did the following:
You set a reference to the code library through the VB IDE
You Dim'd a container for one of the ADO objects
After you had a container object, you instantiated a version of an ADO object into it
After that, you simply invoked its methods and properties as needed.
With Visual Basic.NET, your consumption of Framework classes will follow the exact same pattern.
Not all classes in the Framework Class Library allow you to create instances just by using the New operatorsome force you to go through a class factory method to get your initial instance of the class. The WebRequest class is one example: in order to create a new WebRequest object, you have to use the WebRequest.Create method. You should also be aware that some classes have static methods and properties. Static methods apply to classes and not instances. That means that you don't have to create an instance of the class in order to use the method. The WebRequest.Create method is an example of a static method: we simply call it using the class reference without an actual instance having been created.
Inheriting from the Framework Class Library
With the exception of those classes marked as sealed, you are free to build your own classes on any of the base classes in the library using the inheritance model in .NET.
As you explore the Framework Class Library, you will see many instances of inherited classes that override and overload class members (both of these concepts were discussed in the previous chapter. In the documentation for a specific class, you may see a method defined as Overrides:
Overrides Public Function GetYear(ByVal time As DateTime) As Integer
This example shows the method prototype for the GetYear method on the JulianCalendarClass. It shows us that this function is overridden from its base class (in this case, from the Calendar class).
Overloading is a form of overriding by providing multiple method instances that different only in their parameter list.
As with overriding, you will notice plenty of examples of overloading. Many class constructors are overloaded to give developers the maximum choice of instantiation based on the available data.
Consider the following constructors for the TCPClient class:
Overloads Public Sub New() Overloads Public Sub New(ByVal localEP As IPEndPoint) Overloads Public Sub New(ByVal hostname As String, port As Integer)
These constructors give you the choice of how you want to instantiate a TCPClient object.
By now you'll have noticed that both Visual Basic.NET and the Framework Class Library define base data types. In other words, you have the Int32 data type defined in the System root namespace, and the Integer data type defined in Visual Basic. From a best practices perspective, you may be asking yourself, which is the preferred method: declaring things using VB.NET intrinsics, or their actual System types?
To illustrate, both of the following lines of code are valid:
Dim SomeVar As Integer Dim AnotherVar As System.Int32
We suggest you pick whatever comes more naturally to you, and use it consistently. Using the actual framework data types has some attraction if you are programming across multiple languages; you don't have to shift gears. On the other hand, dimensioning a variable as Integer will come much more naturally to Visual Basic developers. And of course, you don't have to worry about the repercussions of your choice: the CLR ensures that all of your code is mapped to the correct underlying data type.
Exception Handling is the process of managing errors that may be encountered during the execution of your code. The .NET runtime and the .NET languages support the concept of Structured Exception Handling (SEH). These exception handlers follow a standard format that defines a Try block, a Catch block, and a Finally block.
Writing an exception handler requires you to place the code that could possibly generate an error into the Try block. In the Catch block, you place your code that deals with the error. The Finally block is where you place operations that should be performed regardless of whether an error was raised or not. The following code snippet shows a simple routine that implements its code inside of an exception handler.
Sub DoCalc(ByVal num1 As Integer, ByVal num2 As Integer) As Integer 'The exception handler is initiated with the 'try' block Try DoCalc = num1 / num2 Catch appError As Exception 'handle the error; here, we just alert the user 'through a message box. To get more detailed 'debugging level info, we could use the 'Exception.StackTrace property... MsgBox("Error:" & appError.Message) Finally Beep() End Try End Sub
Notice that the Catch statement syntax allows you to deal with the exception as an object. The class library defines an actual Exception class that allows the runtime to treat pass exceptions through as instances of the Exception class. The Exception base class is, in turn, used to derive more specialized exception classes such as the ApplicationException and SystemException classes (both defined in the System root namespace) and the WebException class (defined in the System.Net namespace). In fact, a fairly deep class hierarchy is built from the Exception class base (see Figure 4.1).
As you examine the Exception class descendants, you will see that they offer methods and properties specific to a given coding scenario. They often, for instance, override the ErrorCode property to provide specific error codes for their particular scope. An exception handler with multiple catch blocks looks like this:
'The exception handler is initiated with the 'try' block Try 'code that could raise an exception goes here Catch appError As Exception 'handle the generic error Catch win32Error As Win32Exception 'handle win32 error Catch sockError As SocketException 'handle network socket error Finally 'code to run regardless of exception or not End Try
You can use the appropriate level (generalized or specialized) of exception object that is appropriate to your specific piece of code. You often will use multiple catch blocks in your code to deal with exceptions raised across different levels of the exception class hierarchy.