J

mscorlib (+)■■■■<> Microsoft.Win32 l±l- { } Microsoft.Win32.SafeHandles

■■■{} System 0- { } System .Coll ecti ons 0- { } System .Coll ecti ons. G en eri c 0- { } System .Coll ecti ons. Obj ectM od el 0- { } System. Conf i g u rati on. Assem bl i es 0- { } System. Depl oy m ent.Intern a I [+]•{} System.Diagnostics 0- { } System. Dia gnostics. Cod eAn a lysis 0- { } System. Di a g n osti cs. Sym bol Store 0- { } System. GI oba I izati on 0 {} System.10

m BinaryWriter mBuffered Stream

El ft CloseO

ft Dispose[Boolean]

ft FillBuffer(]nteger]

ft N ew(System IO.Strea m)

ft New[System.IO.Stream, System .Tact. En coding)

ft PeekCharO As Integer ft ReadO As Integer ft Read[ByteO, Integer, Integer] As Integer ft Read[CharO, Integer, Integer] As Integer ft Read7BitEncodedIntO As Integer ft ReadBooleanO As Boolean ft ReadByteQ As Byte ft ReadBvtesflnteger] As Bvtef]_

Public Class BinaryReader

Inherits System.Object Member of System.IO Summary:

Reads primitive data types as binary values in a specific encoding.

Figure 1-5. A single assembly can have any number of namespaces.

The key difference between this approach and a language-specific library such as the Java API is that any language targeting the .NET runtime makes use of the same namespaces and same types. For example, the following three programs all illustrate the ubiquitous "Hello World" application, written in VB 2008, C#, and C++/CLI:

' Hello world in VB 2008

Imports System

Public Module MyApp Sub Main()

Console.WriteLine("Hi from VB 2008") End Sub End Module

using System;

public class MyApp {

static void Main() {

Console.WriteLine("Hi from C#");

#include "stdafx.h" using namespace System;

int main(array<System::String A> Aargs) {

Console::WriteLine(L"Hi from C++/CLI"); return 0;

Notice that each language is making use of the Console class, which is defined within a namespace named System. Beyond minor syntactic variations, these three applications look and feel very much alike, both physically and logically.

Clearly, your primary goal as a .NET developer is to get to know the wealth of types defined in the (numerous) .NET namespaces. The most fundamental namespace to get your hands around is named System. This namespace provides a core body of types that you will need to leverage time and again as a .NET developer. In fact, you cannot build any sort of functional .NET application without at least making a reference to the System namespace. Table 1-2 offers a rundown of some (but certainly not all) of the .NET namespaces.

Table 1-2. A Sampling of.NETNamespaces

.NET Namespace

Meaning in Life

System

System.Collections System.Collections.Generic

System.Data

System.Data.Odbc

System.Data.OracleClient

System.Data.OleDb

System.Data.SqlClient

System.IO

System.IO.Compression System.IO.Ports

System.Reflection System.Reflection.Emit

System.Runtime.InteropServices

System.Drawing System.Windows.Forms

Within System you find numerous useful types dealing with intrinsic data, mathematical computations, random number generation, environment variables, and garbage collection, as well as a number of commonly used exceptions and attributes.

These namespaces define a number of stock container types, as well as base types and interfaces that allow you to build customized collections.

These namespaces are used for interacting with relational databases using ADO.NET.

These namespaces define numerous types used to work with file I/O, compression of data, and port manipulation.

These namespaces define types that support runtime type discovery as well as dynamic creation of types.

This namespace provides facilities to allow .NET types to interact with "unmanaged code" (e.g., C-based DLLs and COM servers) and vice versa.

These namespaces define types used to build desktop applications using .NET's original UI toolkit (Windows Forms).

.NET Namespace

Meaning in Life

System.Windows

System.Windows.Controls

System.Windows.Shapes

System.Linq

System.Xml.Linq

System.Data.Linq

System.Web System.ServiceModel

System.Workflow.Runtime System.Workflow.Activities

System.Threading

System.Security

System.Xml

The System.Windows namespace is the root for several new namespaces (introduced with .NET 3.0) that represent the Windows Presentation Foundation UI toolkit.

These namespaces define types used when programming against the LINQ API.

This is one of many namespaces that allow you to build ASP.NET web applications and XML web services.

This is one of many namespaces used to build distributed applications using the (.NET 3.0-centric) Windows Communication Foundation API.

These are two of many namespaces that define types used to build "workflow-enabled" applications using the .NET 3.0 Windows Workflow Foundation API.

This namespace defines numerous types to build multithreaded applications.

Security is an integrated aspect of the .NET universe. In the security-centric namespaces, you find numerous types dealing with permissions, cryptography, and so on.

The XML-centric namespaces contain numerous types used to interact with XML data.

Note Chapter 2 will illustrate the use of the .NET Framework 3.5 SDK documentation, which provides details regarding every namespace and type found within the base class libraries.

Accessing a Namespace Programmatically

It is worth reiterating that a namespace is nothing more than a convenient way for us mere humans to logically understand and organize related types. Consider again the System namespace. From your perspective, you can assume that System.Consolerepresents a class named Console that is contained within a namespace called System. However, in the eyes of the .NET runtime, this is not so. The runtime engine only sees a single entity named System.Console.

In Visual Basic 2008, the Imports keyword simplifies the process of referencing types defined in a particular namespace. Here is how it works. Let's say you are interested in building a traditional desktop application. The main window renders a bar chart based on some information obtained from a back-end database and displays your company logo. While learning the types each namespace contains takes study and experimentation, here are some possible candidates to reference in your program:

' Here are all the namespaces used to build this application.

Imports System Imports System.Drawing Imports System.Windows.Forms Imports System.Data Imports System.Data.SqlClient

General base class library types. Graphical rendering types. GUI widget types. General data-centric types. MS SQL Server data access types.

Once you have specified some number of namespaces (and set a reference to the assemblies that define them, which is explained in Chapter 2), you are free to create instances of the types they contain. For example, if you are interested in creating an instance of the Bitmap class (defined in the System.Drawing namespace), you can write the following:

' Explicitly list the namespaces used by this file.

Imports System Imports System.Drawing

Public Class Program Public Sub DisplayLogo()

' Create a 20 x 20 pixel bitmap.

Dim companyLogo As New Bitmap(20, 20)

End Sub End Class

Because your application is importing System.Drawing, the compiler is able to resolve the Bitmap class as a member of this namespace. If you did not specify the System.Drawing namespace, you would be issued a compiler error. However, you are free to declare variables using a fully qualified name as well:

' Not listing System.Drawing namespace!

Imports System

Public Class Program Public Sub DisplayLogo()

' Create a 20 x 20 pixel bitmap.

Dim companyLogo As New System.Drawing.Bitmap(20, 20)

End Sub End Class

While defining a type using the fully qualified name provides greater readability, I think you'd agree that the VB 2008 Imports keyword reduces keystrokes. In this text, I will avoid the use of fully qualified names (unless there is a definite ambiguity to be resolved) and opt for the simplified approach of the Imports keyword.

However, always remember that this technique is simply a shorthand notation for specifying a type's fully qualified name, and each approach results in the exact same underlying CIL (given the fact that CIL code always makes use of fully qualified names) and has no effect on performance or the size of the generated assembly.

Referencing External Assemblies

In addition to specifying a namespace via the VB 2008 Imports keyword, you also need to tell the VB 2008 compiler the name of the assembly containing the actual CIL definition for the referenced type. As mentioned, many core .NET namespaces live within mscorlib.dll. However, the System. Drawing.Bitmap type is contained within a separate assembly named System.Drawing.dll. A vast majority of the .NET Framework assemblies are located under a specific directory termed the global assembly cache (GAC). On a Windows machine, this can be located under C:\Windows\assembly, as shown in Figure 1-6.

Figure 1-6. The base class libraries reside in the GAC.

Depending on the development tool you are using to build your .NET applications, you will have various ways to inform the compiler which assemblies you wish to include during the compilation cycle. You'll examine how to do so in the next chapter, so I'll hold off on the details for now.

Using ildasm.exe

If you are beginning to feel a tad overwhelmed at the thought of gaining mastery over every namespace in the .NET platform, just remember that what makes a namespace unique is that it contains types that are somehow semantically related. Therefore, if you have no need for a user interface beyond a simple console application, you can forget all about the System.Windows and System.Web namespaces (among others). If you are building a painting application, the database namespaces are most likely of little concern. Like any new set of prefabricated code, you learn as you go. (Sorry, there is no shortcut to "magically" know all the assemblies, namespaces, and types at your disposal; then again, that is why you are reading this book!)

The Intermediate Language Disassembler utility (ildasm.exe) allows you to load up any .NET assembly and investigate its contents, including the associated manifest, CIL code, and type metadata. By default, ildasm.exe should be installed under C:\Program Files\Microsoft SDKs\Windows\ V6.0A\Bin (if you cannot find ildasm.exe in this location, simply search your machine for an application named "ildasm.exe").

Note If you have installed Visual Studio 2008, you can also load ildasm.exe by opening a Visual Studio 2008 Command Prompt (see Chapter 2 for details) and typing the name of the tool (ildasm) and pressing the return key.

Once you loaded this tool, proceed to the File >- Open menu command and navigate to an assembly you wish to explore. By way of illustration, Figure 1-7 shows the Calc.exe assembly built by compiling the Calc.vb code file seen earlier in this chapter. As you can see, ildasm.exe presents the structure of an assembly using a familiar tree-view format.

Figure 1-7. ildasm.exe allows you to view the internal composition of any .NET assembly.

Viewing CIL Code

In addition to showing the namespaces, types, and members contained in a given assembly, ildasm.exe also allows you to view the CIL instructions for a given member. For example, if you were to double-click the Main() method of the Program type, a separate window would display the underlying CIL (see Figure 1-8).

J/ Ca IculatorExample. Prog ram:: Ma in : voidQ

Find Find Next

|.method public static uoid Main() cil managed

.entrypoint

.custom instance uoid [mscorlib]System.STAThreadAttribute::.ctor() = ( // Code size 40 (0x28)

.maxstack 3

.locals init (int32 U_0, class CalculatorExample.Calc U_1)

IL IL"

neuobj stloc.1 ldloc.1 ldc.i4.s ldc.i4.s calluirt instance uoid CalculatorExample .Calc:: .ctorQ

Was this article helpful?

0 0

Post a comment