BUY THIS BOOK
Add to Cart

Print Book $44.95


Safari Books Online

What is this?

Add to UK Cart

Print Book £31.95

What is this?

Looking to Reprint this content?


VB.NET Core Classes in a  Nutshell
VB.NET Core Classes in a Nutshell

By Budi Kurniawan, Ted Neward
Price: $44.95 USD
£31.95 GBP

Cover | Table of Contents | Colophon


Table of Contents

Chapter 1: Introduction
The .NET Framework is Microsoft's new computing platform that simplifies the design, development, and deployment of computer applications. Developed particularly to facilitate the creation of Internet applications and distributed Internet applications, the .NET Framework features the .NET Framework Class Library (FCL), a systematic class framework to be used for the development of system tools and utilities as well as application software. This chapter assesses the significance of the .NET FCL and discusses accessing it from Visual Basic code.
Although programmers using languages like C++ have been using frameworks for system and application development from the very inception of their language (the Microsoft Foundation Class Library, or MFC, for instance, is a framework for developers of Windows applications using C++), comprehensive frameworks or class libraries are comparatively rare in Visual Basic programming. For the most part, programmers of previous versions of Visual Basic depended on two major sources to extend the Visual Basic language: the Win32 API, and ActiveX servers exposed through COM automation.
The Win32 API is a procedural library that allows the developer to create programs that run under Windows and take advantage of core Windows operating system services. The Win32 API has been enhanced on a regular basis since it was introduced to support Windows NT 3.0, and it now consists of several thousand functions and constants located in a number of dynamic link libraries (DLLs). Because it is a loose collection of functions, there are'nt necessarily any consistent conventions in naming functions or in designating function parameters. The function-based style of programming using the Win32 API has a number of limitations:
Lack of consistency across the entire Win32 API
Although a collection of Win32 API functions may be interdependent, at the same time each function tends to be a more or less independent entity that is called in isolation from other functions in your program. This tends to make the Win32 API as a whole difficult for all programmers to learn and master.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Before the .NET FCL
Although programmers using languages like C++ have been using frameworks for system and application development from the very inception of their language (the Microsoft Foundation Class Library, or MFC, for instance, is a framework for developers of Windows applications using C++), comprehensive frameworks or class libraries are comparatively rare in Visual Basic programming. For the most part, programmers of previous versions of Visual Basic depended on two major sources to extend the Visual Basic language: the Win32 API, and ActiveX servers exposed through COM automation.
The Win32 API is a procedural library that allows the developer to create programs that run under Windows and take advantage of core Windows operating system services. The Win32 API has been enhanced on a regular basis since it was introduced to support Windows NT 3.0, and it now consists of several thousand functions and constants located in a number of dynamic link libraries (DLLs). Because it is a loose collection of functions, there are'nt necessarily any consistent conventions in naming functions or in designating function parameters. The function-based style of programming using the Win32 API has a number of limitations:
Lack of consistency across the entire Win32 API
Although a collection of Win32 API functions may be interdependent, at the same time each function tends to be a more or less independent entity that is called in isolation from other functions in your program. This tends to make the Win32 API as a whole difficult for all programmers to learn and master.
Focus on C programmers
The Win32 API originally was developed as a set of functions that would be called primarily from C code. Although the Win32 API can be called from Visual Basic code, writing code that relies heavily on calls to external DLLs has always been something of an adventure in Visual Basic. Much of the challenge centers on the fact that the type systems used by C and Visual Basic are not completely compatible, so that Visual Basic data types have to be converted to data types expected by C language routines.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The .NET Framework Class Library
The .NET Framework includes the .NET Framework Class Library (FCL), a vast collection of thousands of types (that is, of classes, interfaces, structures, delegates, and enumerations) that aim at encapsulating the functionality of core system and application services in order to make application programming easier and faster. There are classes that you can use to manipulate the file system, access databases, serialize objects, and launch and synchronize multiple threads of execution, to name just a few.
To make working with these classes easy, classes with similar functionality are grouped together in namespaces. Therefore, there is a namespace containing types for drawing, a number of namespaces for .NET remoting, etc. In fact, the "intrinsic" functions of the Visual Basic language (such as InStr, Len, and UBound) are implemented as class methods in the Microsoft.VisualBasic namespace. In total, the .NET FCL places more than 80 namespaces at your disposal.
The .NET FCL includes classes with the following functionality:
Data type definition
Some members of the System namespace, such as the Object, String, Int32, and Single classes, form the data types used by Visual Basic .NET (as well as by other .NET languages that rely on the .NET Common Type System).
Exceptions
When an exception is generated, the CLR provides exception information to the Exception class (in the System namespace) or to one of the derived classes found throughout the .NET FCL.
Events and event handlers
The signature of event handlers is represented by the EventHandler delegate (in the System namespace) or one of its derived delegates. The event information passed to an event handler is represented by the EventArgs class (in the System namespace) or one of its derived classes.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Working with the .NET FCL
Despite its vast size, the .NET FCL is a manageable collection of classes and their methods. This is because, unlike more traditional development tools such as the Win32 API, the .NET FCL is a collection of types (classes, interfaces, delegates, events, structures, modules, and enumerations) and their members organized into namespaces. A namespace is simply a logical grouping of classes that can in turn contain other namespaces, so that a collection of namespaces forms an inverse hierarchical tree. Organization of types into namespaces helps to prevent collisions in the event that types are identically named.
Although the .NET system of namespaces does not have a single root, we can consider the System namespace at the top of the .NET FCL hierarchy. It includes a wide variety of basic system classes, including data types, exception types, and types defining the most important attributes.
The types in a namespace, in turn, reside in an assembly, which is simply a logical unit of deployment. An assembly provides the Microsoft Intermediate Language (MSIL) code for its contents, which is packaged in a Windows portable executable (PE) file. An assembly also specifies security permissions for itself, maintains a list of the types that it defines and their scopes, and specifies rules for resolving references to external types.
The assemblies in which namespaces of the .NET FCL reside are Windows dynamic link libraries (.DLLs). Typically, a single assembly contains multiple namespaces. In addition, however, a single namespace can reside in multiple assemblies. The System namespace, for example, resides in both mscorlib.dll and system.dll.
You can use ILDASM, the Intermediate Language disassembler included with the .NET Framework SDK, to see which namespaces and types are available in a particular assembly or DLL.
Namespaces are made available to Visual Studio or to the Visual Basic compiler by identifying the assembly in which the namespace resides. When using Visual Studio as the development environment for your Visual Basic projects, this is done by using the References dialog, as follows:
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Types of a .NET Namespace
Once you've made a namespace accessible to your code, you can access any of the types it contains. In this section, we'll survey the types that a .NET namespace can contain.
In VB.NET, classes are reference types; that is, when you create an instance of a class in code, you work with a pointer (or reference) to the object rather than with the object itself. This is similar to previous versions of Visual Basic.
When a .NET class is instantiated, its constructor (or its New subroutine) executes. Each .NET class can have one or more constructors (that is, constructors can be overloaded), and the constructor can either be parameterless or parameterized. Visual Basic .NET provides three ways to initialize a variable and invoke its constructor. These are illustrated in the following three sets of statements, each of which instantiates a System.IO.FileInfo object:
' Single statement
Dim oFile As New FileInfo("c:\documents\notes.txt") 
  
' Single Statement with separate call to constructor
Dim oFile As FileInfo = New FileInfo("c:\documents\notes.txt")
  
' Separate declaration and initialization
Dim oFile As FileInfo
oFile = New FileInfo("c:\documents\notes.txt")
Once we create an instance of a class, we can invoke its properties and methods. In addition, we can handle its events (assuming that it exposes events) if we instantiate the object using the WithEvents keyword. For example:
Dim WithEvents cn As New SqlConnection()
Visual Basic .NET, unlike previous versions of Visual Basic, supports both instance and shared members. Instance members exist for each instance of a class; in previous versions of Visual Basic, all members of a class were instance members. Shared members are members that are not associated with a specific instance of a class or a structure, but rather are common to all instances of a class. Accessing a shared member of a class does not require that the class be instantiated; it can be accessed using the class name only. In addition, if the shared member is a property, it has a single value for all instances of the class.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Approaching the .NET FCL
It may seem that, given both the newness and the enormity of the .NET platform, a substantial learning curve is required to "learn" the .NET FCL. In fact, this isn't the case; you can begin to take advantage of the class library immediately by selecting those classes, structures, and enumerations and their members that are of immediate interest to you and ignoring the rest. You can then gradually expand your familiarity with the .NET FCL as needed.
This incremental approach to learning the .NET FCL is possible because Visual Basic was written to run under the .NET platform, and much of the Visual Basic language (or at least the functions and procedures not implemented directly by the Visual Basic compiler) actually wrap functionality found in the .NET FCL.
The clearest example of this is to be found in the data types supported by Visual Basic. While Visual Basic's data types appear to be intrinsic, in fact they are defined by the .NET FCL; Visual Basic merely provides wrappers for each of the .NET data types for which it offers native support. This, in fact, is one of the major strengths of the .NET Framework: it features the Common Type System (CTS), which allows components and applications written in one .NET-compliant language to more or less seamlessly interoperate with components written in other .NET-compliant languages. Table 1-1 shows the "intrinsic" Visual Basic data types and their corresponding .NET FCL data types.
Table 1-1: VB.NET data types and their corresponding .NET FCL data types
VB.NET data type
.NET FCL data type
Boolean
System.Boolean
Byte
System.Byte
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: Reference
The quick-reference section that follows packs a lot of information into a small space. This introductory section explains how to get the most out of that information. It describes how the quick reference is organized and how to read the individual quick reference entries.
The quick reference is organized into chapters, one per namespace. Each chapter begins with an overview of the namespace and includes a hierarchy diagram for the types (classes, interfaces, enumerations, delegates, and structs) in the namespace. Following the overview are quick-reference entries for all of the types in the namespace.
Figure 2-1 is a sample diagram showing the notation used in this book. This notation is similar to that used in Java in a Nutshell (O'Reilly) but borrows some features from UML.
Classes marked as MustInherit are shown as a slanted rectangle, and classes marked as NonInheritable are shown as an octagonal rectangle. Inheritance is shown as a solid line from the subtype, ending with a hollow triangle that points to the base class. There are two notations that indicate interface implementation. The lollipop notation is used most of the time, since it is easier to read. In some cases, especially where many types implement a given interface, the shaded box notation with the dashed line is used.
Important relationships between types (associations) are shown with a dashed line ending with an arrow. The figures don't show every possible association. Some types have strong containing relationships with one another. For example, a System.Net.WebException object instance includes a System.Net.WebResponse object instance that represents the HTTP response containing the error details (HTTP status code and error message). To show this relationship, a filled diamond is attached to the containing type with a solid line that points to the contained type.
Entries are organized alphabetically by type and namespace, so that related types are grouped near each other. Thus, in order to look up a quick reference entry for a particular type, you must also know the name of the namespace that contains that type. Usually, the namespace is obvious from the context, and you should have no trouble looking up the quick-reference entry you want. Use the tabs on the outside edge of the book and the dictionary-style headers on the upper outside corner of each page to help you find the namespace and type you are looking for.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Finding a Quick-Reference Entry
The quick reference is organized into chapters, one per namespace. Each chapter begins with an overview of the namespace and includes a hierarchy diagram for the types (classes, interfaces, enumerations, delegates, and structs) in the namespace. Following the overview are quick-reference entries for all of the types in the namespace.
Figure 2-1 is a sample diagram showing the notation used in this book. This notation is similar to that used in Java in a Nutshell (O'Reilly) but borrows some features from UML.
Classes marked as MustInherit are shown as a slanted rectangle, and classes marked as NonInheritable are shown as an octagonal rectangle. Inheritance is shown as a solid line from the subtype, ending with a hollow triangle that points to the base class. There are two notations that indicate interface implementation. The lollipop notation is used most of the time, since it is easier to read. In some cases, especially where many types implement a given interface, the shaded box notation with the dashed line is used.
Important relationships between types (associations) are shown with a dashed line ending with an arrow. The figures don't show every possible association. Some types have strong containing relationships with one another. For example, a System.Net.WebException object instance includes a System.Net.WebResponse object instance that represents the HTTP response containing the error details (HTTP status code and error message). To show this relationship, a filled diamond is attached to the containing type with a solid line that points to the contained type.
Entries are organized alphabetically by type and namespace, so that related types are grouped near each other. Thus, in order to look up a quick reference entry for a particular type, you must also know the name of the namespace that contains that type. Usually, the namespace is obvious from the context, and you should have no trouble looking up the quick-reference entry you want. Use the tabs on the outside edge of the book and the dictionary-style headers on the upper outside corner of each page to help you find the namespace and type you are looking for.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Reading a Quick-Reference Entry
Each quick-reference entry contains quite a bit of information. The sections that follow describe the structure of a quick-reference entry, explaining what information is available, where it is found, and what it means. While reading the descriptions that follow, you will find it helpful to flip through the reference section itself to find examples of the features being described.
Each quick-reference entry begins with a four-part title that specifies the name, namespace (followed by the assembly in parentheses), and type category of the type, and may also specify various additional flags that describe the type. The type name appears in bold at the upper left of the title. The namespace and assembly appear, in smaller print, in the lower left, below the type name.
The upper-right portion of the title indicates the type category of the type (class, delegate, enum, interface, or struct). The "class" category may include modifiers such as NonInheritable or MustInherit.
In the lower-right corner of the title, you may find a list of flags that describe the type. The possible flags and their meanings are as follows:
ECMA
The type is part of the ECMA CLI specification.
Serializable
The type, or a base class, implements System.Runtime.Serialization.ISerializable or has been flagged with the System.Serializable attribute.
Marshal by reference
This class, or a superclass, derives from System.MarshalByRefObject.
Context bound
This class, or a superclass, derives from System.ContextBoundObject.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 3: Microsoft.Win32
The Microsoft.Win32 namespace includes types you can use to interact with the Microsoft Windows platform. These types concentrate on two aspects of Windows-specific programming: receiving operating system events and manipulating the registry. Essentially, the classes, delegates, and enumerations in this namespace provide a type-safe object wrapper around a few select functions in the Windows API.
Use the Registry class to access the root level registry keys, which are provided as RegistryKey objects. These have built-in methods for retrieving and modifying key values. The SystemEvents class allows you to respond to system events such as timers, preference changes, and shutdown operations. All other types in this namespace are used to support the SystemEvents class, by providing delegates for each event and custom System.EventArgs objects that provide additional information to the corresponding event handlers. Figure 3-1 shows the inheritance diagram for this namespace.
Figure 3-1: The Microsoft.Win32 namespace
PowerModeChangedEventArgs
This class creates a custom System.EventArgs object for the PowerModeChangedEventHandler delegate. It provides additional information to your event handler, identifying the new power mode that the system has entered.
Public Class PowerModeChangedEventArgs : Inherits EventArgs ' Public Constructors Public Sub New( ByVal mode As PowerModes) ' Public Instance Properties Public ReadOnly Property Mode As PowerModes End Class
Hierarchy
System.Object System.EventArgs PowerModeChangedEventArgs
Passed To
PowerModeChangedEventHandler.{BeginInvoke()
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 4: System
In many respects, the System namespace serves as the core namespace for the .NET libraries, in much the same way java.lang does for Java programmers or stdlib.h does for C/C++ programmers. For example, the ECMA-compliant primitive-type value types are defined in the System namespace, along with complementary composite types and base types. These are used in the synthesis of type generation, which is done by the compiler on the .NET programmer's behalf (for an example of this on-the-fly type synthesis, see Array). Figure 4-1 shows many of the types in this namespace.
System serves as the home for key base-type definitions, including Object, the root of every type in the .NET hierarchy. Every type in the system ultimately extends this class, making it the "root of all evil" in .NET. In addition, this namespace contains ValueType, the base type for all value types in .NET (such as the primitive types listed later in this chapter, shown in Figure 4-5), and Type, which in turn represents compile-time type information about other types defined within the .NET environment (the type metadata).
ECMA-compliant primitive-type value types include the fundamental types used for all .NET applications, which are basic value types such as Int32, Single, Double, Decimal, Char, Byte, and Boolean. All of the primitive types are aliased in VB.NET with keywords such as Integer, Double, and Boolean. See the description of each type for more details. In addition to these fundamental types, there are composite types such as DateTime and TimeSpan, used to handle date- and time-based calculations without having to drop down to integer math, and Uri, used to represent references to a Universal Resource Identifier, which is the more generic form of the ubiquitous HTTP URL identifier used on the Web.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 5: System.Collections
The System.Collections namespace provides basic functionality for collections of objects. It defines interfaces, base classes, and implementations for collections such as dictionaries, sorted lists, queues, and stacks. The base classes can also be extended to create specialized collection types. However, the System.Collections.Specialized namespace contains a set of extended collection types based on this namespace, so check there before creating your own types. Figure 5-1 and Figure 5-2 show the types in this namespace.
On first observation, the design of these collections seems somewhat awkward — for example, why does a "list" seem to be broken into two pieces: the IList interface and the ArrayList implementation? On top of this, the namespace defines a number of other interfaces, such as IEnumerable and IEnumerator, that seem unnecessary.
In fact, the design of the collection types in this namespace is quite similar to the designs of other container libraries such as the STL (Standard Template Library) in C++ and the Java Collections library in JDK 1.2. By separating the interface of a collection type (the concept of "list-ness" or "dictionary-ness") from the actual implementation, you are free to assume only the absolute minimum about the actual implementation used, and instead focus only on what is needed in order to carry out the work. For example, VB.NET's For Each construct works by silently using the IEnumerable interface to obtain an object that inherits the IEnumerator interface. Thus, a programmer could, if desired, create a custom type (perhaps modeling a hand of cards) that acts just as any other collection class does. Alternatively, the iterator (the type that inherits from IEnumerator) could be a "smart" iterator, knowing how to walk through (or skip past) types in the container itself. All this is possible solely because the interface is separated from the implementation; it is decoupled.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 6: System.Collections.Specialized
The types defined in the System.Collections namespace are fine as general-purpose collection types, but frequently programmers require specialized semantics around a collection class; for example, storing a collection of booleans could be more efficiently stored as a single System.Int64, whereas simply placing System.Boolean instances into a general-purpose collection is far more wasteful, in both memory and processing time.
Additionally, programmers often grow frustrated with the lack of type-safety in the general-purpose containers; not only does a programmer have to typecast any object obtained out of the container, but the container itself holds no intrinsic logic to "screen out" unwanted types being inserted into the container. (This is in marked contrast to C++ template-based collections such as the STL, in which the attempt to put a string into a container of integers causes a compile-time error.)
Container specialization isn't limited to storage type — at times, a programmer desires different processing behavior than the general-purpose container provides. As an example, consider the System.Collections.IDictionary interface. Note that it clearly defines a mapping of keys to values; however, it is only implicitly understood that the exact same key must be produced to obtain the value desired. In most cases, this is exactly what's needed; however, there are times when a less stringent retrieval mechanism is preferred. For example, perhaps a case-insensitive match is wanted instead of doing an exact-match for a string key. The System.Collections.Specialized namespace includes collections designed to address these cases. Figure 6-1 shows the types in this namespace.
Figure 6-1: The System.Collections.Specialized namespace
BitVector32
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 7: System.Diagnostics
Diagnostics are an important part of any software system. In addition to the obvious necessity of debugging the code, diagnostics can keep track of application performance and liveness, thus indicating a problem proactively, rather than waiting for the phone call from the system administrators.
Diagnostics means more than just compiling with debug symbols turned on. Certain code paths might want to execute only when diagnostics are turned on to full power, indicated by a compile-time switch. At other times, particularly in long-running systems (such as WebService-based systems), developers want to keep a log of the system's actions; frequently, debug reports from users are sketchy ("Um, when I clicked the button, it all just crashed"), and having a complete log of the system's actions can be invaluable in tracking the problem down. Not only can the log consist of custom-written messages (usually to a file), but the Windows Event Log is also available for use from within this namespace.
Diagnostics also includes the ability to track the health and performance of the application; under Windows 2000 and XP, this means interaction with the Performance utility. This is a powerful tool that can be launched from the Administrative Tools program group (under Windows NT, it is called Performance Monitor). By creating appropriate performance counters within the application, .NET programmers can give the system support staff (system administrators and production monitoring personnel, among others) the ability to monitor and track the application, even remotely. In addition to its diagnostic facilities, this namespace exposes operating system processes using the Process type. Use this type to launch new processes or take control of processes currently running on the system. The ProcessThread type lets you drill down into each thread that's running within a process for fine-grained control over running applications.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 8: System.Globalization
The System.Globalization namespace provides classes that assist in localization of applications based on language and culture. The CultureInfo class is the primary container for a set of resources that is used for a specified language and culture implementation. It describes how strings are sorted, the specifics of calendars and date and time formats, as well as language and dialect code pages. An application obtains its culture information based on either the CultureInfo specified by the current thread or from the user or local machine's preferences. Specific cultural information is contained in resource files deployed in satellite assemblies. System.Resources.ResourceManager marshals these resource files into System.Resources.ResourceSets that provide the objects and methods specific to a localization.
The System.Globalization namespace provides a base Calendar class, as well as specific calendar implementations for major cultures. CompareInfo defines how string comparison and sorting are handled. DateTimeFormatInfo defines how DateTime values are formatted, and NumberFormatInfo defines various formatting styles, such as currency symbols and decimal and grouping separators. Figure 8-1 shows the types in this namespace.
Figure 8-1: The System.Globalization namespace
Calendar
This MustInherit class determines the division and measurement of time in units, such as day, months, years, and eras. It is a MustInherit base class for culture-specific calendar implementations included in this namespace. Derived classes store the specific information about a calendar's eras, lengths of years and months, and the sometimes esoteric rules for calculating leap years. These properties get used by DateTimeFormatInfo to properly display a date and time string from a specific
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 9: System.IO
The System.IO types serve as the primary means for stream-oriented I/O — files, principally, although the MustInherit types defined here serve as base classes for other forms of I/O, such as the XML stack in System.Xml. The System.IO namespace is shown in Figure 9-1 and Figure 9-2.
The System.IO namespace can be seen as two distinct partitions: a set of utility types for using and working with the local machine's filesystem, and a protocol stack for working with bytestream-oriented input and output. The former partition is the collection of classes such as Directory and FileSystemWatcher, whereas the latter partition is the set of Stream and Reader/Writer types.
The Stream types in System.IO follow a basic object model, similar to the I/O model used by the C/C++ runtime library: all serial byte access is a stream, and there are different sources and sinks for this serialized byte data. In the System.IO package, this is represented directly by the MustInherit base type Stream; its concrete subtypes represent the actual I/O access: FileStream represents I/O to a file, and MemoryStream represents I/O to a literal array of bytes (whose size is dynamically managed) in memory. Other packages within the .NET Framework Class Library offer up their own Stream-derived types. For example, in the System.Net namespace, socket connections and HTTP responses are offered up as Stream-derived types, giving .NET programmers the ability to treat any sort of input or output data as "just a Stream."
Simply reading and writing to these streams is not enough of an abstraction, however. In particular, programmers often need to perform one of two sorts of I/O: binary I/O, which is writing actual binary representations of objects or data to disk, or text I/O, which is writing the textual representations of that data. These operations are fundamentally different — writing the text representation of the integer value 5 produces the literal text "5" within the stream, whereas writing the binary value generates the hex value 0x00000005 (represented as four bytes, 05 00 00 00, in the file). In the .NET libraries, because these types of I/O operations are different from one another, these operations are abstracted out into two sets of MustInherit base types.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 10: System.IO.IsolatedStorage
System.IO.IsolatedStorage allows you to access an isolated area of a filesystem for your application. This is useful when access to the System.IO classes is not possible. The security settings of the .NET Framework prohibit web applications and downloaded controls from accessing the local filesystem directly, but those settings allow them to use System.IO.IsolatedStorage. Applications' storage areas are isolated from one another, so anything in isolated storage is protected from untrusted applications. The size of isolated storage is limited, so an untrusted application cannot create a denial-of-service condition by filling your hard disk with data.
When you use isolated storage, the runtime sets aside disk space for a given level of isolation (specified using IsolatedStorageScope). If you use Windows 2000 or XP, <SYSTEMDRIVE>\Documents and Settings\<user>\Application Data contains the isolated storage area if roaming is turned on, and <SYSTEMDRIVE>\Documents and Settings\<user>\Local Settings\Application Data contains the storage area if roaming is not on. Applications can use this area as a data store for their particular persistence needs. Figure 10-1 shows the inheritance diagram for this namespace.
Figure 10-1: The System.IO.IsolatedStorage namespace
INormalizeForIsolatedStorage
This interface exposes Normalize(), which returns a normalized copy of the object on which it is called. You usually use this method if you are inheriting from IsolatedStorage and you want to see if a store already exists.
Public Interface INormalizeForIsolatedStorage ' Public Instance Methods Public Function
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 11: System.Net
System.Net supports a high-level API for working with common Internet protocols (HTTP being the principal example) without having to deal with low-level details (such as the actual protocol format). In addition, this namespace provides some high-level constructs for working with networks — TCP/IP in particular.
Most .NET programmers will work with either the WebClient type, which provides the most high-level view of doing HTTP-style request/response communications over a TCP/IP network (such as the Internet), or else the slightly lower-level WebRequest and WebResponse types. The choice between the two is really not all that difficult — for most high-level, protocol-agnostic work, WebClient will likely be the preferred choice. If protocol-specific actions need to be taken (such as specifying additional headers as part of an HTTP request, for example), then likely the .NET programmer will want to work with WebRequest and WebResponse. To be specific, the .NET programmer will work with the concrete derived types HttpWebRequest and HttpWebResponse.
As shipped, the .NET Framework Class Library provides implementations for three URI protocol schemes: HTTP, HTTPS, and files (http:, https:, and file:, respectively). For support of other URI types (such as FTP, NNTP, or POP3), a new derivative of WebRequest and WebResponse must be written, an Abstract Factory type implementing the IWebRequestCreate interface must be created, and an instance of it (along with the protocol scheme prefix) must be registered with WebRequest.RegisterPrefix(). Figure 11-1 shows the collaborations between the concrete classes HttpWebRequest, HttpWebResponse, FileWebRequest, and FileWebResponse.
Figure 11-2 shows the composition of the ServicePoint class, and Figure 11-3 shows the remaining types in this namespace.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 12: System.Net.Sockets
The System.Net.Sockets namespace classes implement standard Berkeley sockets APIs for cross-process/cross-host communication. Sockets are low-level objects (abstractions, really) that provide the foundation for most Internet networking. A socket binds to a local address and port, and either waits for a connection from a remote address or connects to a remote address and exchanges data across the network. Two socket implementations are made available in this namespace, TCP/IP and UDP/IP. Most Internet applications, such as FTP clients and web browsers, are built upon socket connections.
Although many system-level programmers feel a close kinship with these types, .NET programmers are greatly encouraged to consider using higher-level constructs, such as HTTP (see the System.Net namespace) or the System.Runtime.Remoting types, to facilitate remote communications. If you need to work at the socket level, consider using TcpClient or TcpListener. These are high-level abstractions of the socket API that support client and server functionality.
For more details regarding many of the options mentioned in this namespace, consult a low-level sockets reference, such as W. Richard Stevens' "Network Programming in the Unix Environment" (Volumes 1 and 2) or "TCP/IP Illustrated" (Volumes 1, 2, and 3). Although the books were written for a Unix environment, .NET faithfully mirrors much, if not all, of the Berkeley sockets API (which originally came from Unix). Figure 12-1 shows the types in this namespace.
Figure 12-1: The System.Net.Sockets namespace
AddressFamily
This enumeration contains values to specify the address family used by a socket. This indicates to which family of addressing schemes the address of the socket belongs. Note that the standard four-digit IP scheme falls under the enumeration
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 13: System.Reflection
System.Reflection is the API that exposes the full-fidelity metadata of the .NET environment to the .NET programmer. In short, it permits complete access to compile-time data at runtime. Everything is available, including fields, methods, constructors, properties, delegate types, and events. The reflection API (as exposed by the System.Reflection namespace) offers some truly unique capabilities unavailable in other compile-time bound languages such as C++. The closest the average COM programmer has come to using reflection is the IDispatch interface and/or type libraries. Reflection, fortunately, is at once both easier to use and far more powerful.
Reflection offers up a number of possible approaches to use. Introspection is the act of using the reflection APIs to discover information about a component assembly (and its constituent types) at runtime without any prior (compile-time) knowledge of it. This approach was first popularized by tools such as Visual Basic and numerous Java IDEs that offered GUI-based construction of visual interfaces. The third-party component was dropped into some well-known location, and the IDE "discovered" it and offered it on a toolbar the next time the IDE was started.
Along similar lines, reflection is often used as part of development tools; for example, the .NET utility xsd.exe uses metadata to generate XML Schema documents that correspond to .NET declared types. A .NET programmer could use reflection to generate SQL (Structured Query Language) statements for storing object instances into a relational database, or even into the SQL DDL (Data Definition Language) itself. Other tools could produce remoting proxies, transparently adding the necessary code to marshal and unmarshal parameters and return values across a network connection, even for types that weren't designed to be remoted in the first place.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 14: System.Reflection.Emit
There are several ways to use reflection in .NET. Reflection can be used for runtime-type inspection and late-bound object creation using the types in the System.Reflection namespace. Reflection can also be used for dynamic code creation, which is supported by the types in this namespace, System.Reflection.Emit. Dynamic code creation means a programmer can programmatically create code constructs such as methods and events from within code, using the appropriate corresponding type (for example, MethodBuilder and EventBuilder). These code elements are all ingredients that can be added to a dynamic assembly, represented by an AssemblyBuilder object. Dynamic assemblies can be saved to disk as PE (Portable Executable) files, typically in DLL form. Or, alternatively, emit it directly to memory for immediate use, at the expense of persistence (memory-only types disappear when the containing AppDomain terminates).
The ILGenerator class allows you to emit the MSIL (Microsoft Intermediate Language) for your code, using the corresponding GetILGenerator() method from a builder class. This process (sometimes known as "baking") allows you to convert the information in the builder object into a legitimate .NET type. You can then instantiate this newly created type on the spot.
The primary use of the System.Reflection.Emit namespace is to create compilers and script hosts, although many other uses are possible, including programs that dynamically create code that is fine-tuned to process a specific regular expression (see System.Text.RegularExpressions.Regex.CompileToAssembly()). When creating dynamic types, you generally begin by creating an AssemblyBuilder, which contains one or more ModuleBuilder objects. This in turn contains TypeBuilder instances. TypeBuilder objects contain most of the other ingredients in this namespace, including classes for building events, properties, methods, and enumerations.
Many of the builder classes in this namespace use similar methods and properties for retrieving information about the containing module (for example,
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 15: System.Runtime.InteropServices
The types in this namespace work with unmanaged code using either PInvoke or COM. PInvoke (short for Platform Invoke) lets you access functions that reside in underlying operating system-specific shared libraries (on Win32, these are DLLs). COM (Component Object Model) is a Win32 legacy component architecture that is used throughout Windows and Windows applications. Many programmers experience COM through the object models of applications such as Microsoft Office, Exchange, and SQL Server. The COM support in .NET lets you access COM components as though they were native .NET classes.
We have omitted some of the more esoteric parts of this namespace, so there are some classes that aren't discussed here. For the most part, you will not need those classes unless you are developing specialized code that handles marshaling data types between managed and unmanaged code. If so, you should consult the MSDN .NET reference materials. Figure 15-1 and Figure 15-2 show the types in this namespace.
Figure 15-1: The System.Runtime.InteropServices namespace
Figure 15-2: Attributes and delegates from System.Runtime.InteropServices
ArrayWithOffset
This class converts an array of value type instances to an unmanaged array. Your unmanaged code accesses this array as a pointer that initially points to the first array element. Each time the pointer increments, it points to the next element in the array. The constructor takes a mandatory offset argument that specifies which element should be the first element in the unmanaged array. If you want to pass the whole array, specify an offset of zero.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 16: System.Runtime.Serialization
The act of serialization transforms an object (and all of its associated objects and/or data elements) into a stream of bytes, suitable for storage or transmission across a network. The reverse of this act, called deserialization, is to take the same stream of bytes and reconstitute the objects exactly as they were at the time of serialization.
This act, which sounds simple in theory, encompasses a number of points that must be addressed. For starters, the serialization libraries must provide complete reference semantics — that is, if an object holds two references to other objects, both of which happen to point to the same object, then the serialization mechanism needs to keep that in place. Therefore, when the stream is deserialized, both references point to the same object again.
In addition, the actual format of the stream of bytes may be different from application to application. For example, for storage into a binary column in a database, the serialized representation must be as compact and succinct as possible — no "wasted" bytes. But if we want to send the serialized data over an HTTP link to a non-.NET process, then a binary format is entirely inappropriate, and an XML-based one is more useful.
The System.Runtime.Serialization namespace and its child namespace, System.Runtime.Serialization.Formatters (with its own two child namespaces, System.Runtime.Serialization.Formatters.Binary, and System.Runtime.Serialization.Formatters.Soap), directly addresses these needs. System.Runtime.Serialization contains the types necessary to perform the serialization of an object into a stream of bytes, using an alternative object (which implements the IFormatter interface) to actually format the bytes into either binary or XML form. While it is certainly feasible to write your own custom formatters, most .NET programmers have no real practical need to do so, since a binary format and an XML format cover most needs.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 17: System.Runtime.Serialization.Formatters
This chapter covers the System.Runtime.Serialization.Formatters namespace, which contains a number of types that are used by serialization formatters. Figure 17-1 shows the types in this namespace. This chapter also features the BinaryFormatter and SoapFormatter, two formatters that live in their own namespace and rely on the types in the System.Runtime.Serialization.Formatters namespace.
Figure 17-1: The System.Runtime.Serialization.Formatters namespace
BinaryFormatter
This formatter uses a binary format to serialize or deserialize a single object or an object graph.
Public NotInheritable Class BinaryFormatter : Implements System.Runtime.Remoting.Messaging.IRemotingFormatter, System.Runtime.Serialization.IFormatter ' Public Constructors Public Sub New() Public Sub New( ByVal selector As System.Runtime.Serialization.ISurrogateSelector, ByVal context As System.Runtime.Serialization.StreamingContext) ' Public Instance Properties Public Property AssemblyFormat As FormatterAssemblyStyle Public Property