Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Pro Visual C++-CLI And The .NET 2.0 Platform (2006) [eng]-1

.pdf
Скачиваний:
70
Добавлен:
16.08.2013
Размер:
24.18 Mб
Скачать

188

C H A P T E R 4 A D V A N C E D C + + / C L I

source->OnSay += gcnew SayHandler(this, &EventReceiver1::SayHello); source->OnSay += gcnew SayHandler(this, &EventReceiver1::SayStuff);

}

void RemoveStuff()

{

source->OnSay -= gcnew SayHandler(this, &EventReceiver1::SayStuff);

}

void SayHello(String ^name)

{

Console::Write("Hello there "); Console::WriteLine(name);

}

void SayStuff(String ^name)

{

Console::Write("Nice weather we are having. Right, "); Console::Write(name);

Console::WriteLine("?");

}

};

ref class EventReceiver2

{

EventSource ^source; public:

EventReceiver2(EventSource ^src)

{

if (src == nullptr)

throw gcnew ArgumentNullException("Must pass an Event Source");

source = src;

source->OnSay += gcnew SayHandler(this, &EventReceiver2::SayBye);

}

void SayBye(String ^name)

{

Console::Write("Good-bye "); Console::WriteLine(name);

}

};

void main()

{

EventSource ^source = gcnew EventSource();

EventReceiver1 ^receiver1 = gcnew EventReceiver1(source);

EventReceiver2 ^receiver2 = gcnew EventReceiver2(source);

source->Say("Mr Fraser");

C H A P T E R 4 A D V A N C E D C + + / C L I

189

Console::WriteLine("-------------------------------"); receiver1->RemoveStuff();

source->Say("Stephen");

}

Figure 4-13 shows the results of this little program.

Figure 4-13. Results of Events.exe

Summary

In this chapter, you looked at some more advanced C++/CLI language topics. You started with the preprocessor directives, and then you moved on to multifile software development. Next, you covered templates, typedef, and exceptions, and finally, you ended with delegates and events.

This chapter covered a lot of new ground for the traditional C++ developer, though much of it had a very familiar flavor to it. You use much of this chapter later in the book, so a good understanding of these topics is essential.

Okay, you have finally covered C++/CLI as a language. In the next chapter, you make your first real foray into the world of .NET software development by looking at the .NET Framework class library.

P A R T 2

■ ■ ■

.NET Framework

Development in C++/CLI

C H A P T E R 5

■ ■ ■

The .NET Framework Class Library

To put it bluntly, the .NET Framework class library is just plain huge. One chapter could never do it justice. There are, in fact, several books devoted solely to describing all the interfaces, structures, enumerations, classes, methods, variables, and so on, that are contained within this library. This chapter’s goal is to focus on giving you a head start in learning how to navigate through this massive library.

Even though the library is big, it is well organized and (gasp!) well documented. Once you understand the basics of how the library is organized, it will be easy for you to locate what you are looking for. It should also be quite simple to figure out if what you are looking for is not included in the library.

I just briefly touch upon the contents of the class library here. In the following chapters, I delve deeper into many specific areas in the library.

Library Organizational Structure

The first thing you need to know about the .NET Framework class library is that it is an object-oriented tree derived from a single root: System::Object. The next important characteristic is that the .NET Framework class library strictly follows the rules specified by the common language specification (CLS), covered in Chapter 1. The key rules that you should be aware of are as follows:

Global functions and variables are not allowed.

There is no imposed case sensitivity (a consequence of the need to support languages like Visual Basic .NET), so all exposed types differ by more than their case. In other words, all public or protected members differ by more then just case.

The primitive types allowed as parameters conform to the CLS, namely, Byte, Int16, Int32,

Int64, Single, Double, Boolean, Char, Decimal, IntPtr, and String.

Variable-length parameter lists to methods are not allowed. Fixed-length arrays are used as parameters instead.

Pointers are not allowed.

Class types must inherit from a CLS-compliant class.

Only single class inheritance is allowed, although multiple inheritance of interfaces is permitted.

Another important aspect of the .NET Framework class library is that the current version is broken up into nearly 100 namespaces. Unlike many other libraries, the component identifiers used for the namespaces are self-describing and thus have the benefit of making it easy to understand what functionality resides within a namespace.

193

194 C H A P T E R 5 T H E . N E T F R A M E W O R K C L A S S L I B R A R Y

You should be aware that even though namespaces in the .NET Framework class library appear to be broken up into a hierarchy, there is, in fact, no actual “class inheritance hierarchy” that corresponds directly to this “namespace hierarchy.” Instead, the namespaces are simply a way of organizing classes into common functionality groups. For example, there is a “namespace hierarchy” of System::Collections::Specialized, but many of the classes found in the

System::Collections::Specialized namespace don’t inherit from System::Collections.

The .NET Framework class library is physically made up of multiple assembly .dlls, which you have to add references to in your code either using the #using statement or in the program’s reference properties, if using Visual Studio 2005. An assembly does not necessarily correspond directly to a namespace, as an assembly may contain multiple namespaces. Also, some of the namespaces spread across multiple assemblies. This does complicate things, as there is no one-to-one correlation, but the .NET Framework class library has placed the most commonly used classes into one assembly: mscorlib.dll. Then, it spread out the less common classes into assemblies made up of common functionality.

Unfortunately, I know of no way to easily figure out which assembly contains which classes. I’ve tried to help you in this regard by pointing out the necessary assemblies to include for each namespace. The only other way I know of to figure out which assembly is needed (other than looking it up in the

.NET documentation) is to look for the C1190 error when compiling (I suppose “linking” is more accurate). This error tells you which assembly is missing.

Library Namespaces

It’s unlikely that you’ll use every namespace in the .NET Framework class library. (That’s not to say you won’t—it’s just unlikely.) Instead, you’ll probably work with the subset of namespaces described in the sections that follow.

I will start with the root namespace System and then progress alphabetically through the most common namespaces. This chapter will not provide you everything you need to implement the classes within a namespace. Instead, it will give you an understanding of what functionality resides within it. If you want a deeper understanding of all the details of the classes within a namespace

(I do not cover the namespace in the subsequent chapters), then I suggest you peruse the documentation provided with the .NET Framework, as it is remarkably well done.

System

The System namespace is the root of the .NET Framework class library namespace hierarchy. The namespace is defined within the mscorlib.dll assembly.

Unlike the other namespaces of the .NET Framework class library, which focus on a particular area of functionality, the System namespace is more a mishmash of core data types and basic functionality that is needed by the rest of the namespace hierarchy.

The most important class within the System namespace is probably the Object class because it is the root of all other classes found within the class library. When you create C++/CLI ref classes of your own, the Object class is inherited by default if you do not specify a parent class. Remember that because C++/CLI ref classes can only inherit from other C++/CLI ref classes, ultimately your class will inherit the Object class.

Some of the other common functional areas covered by the System namespace are as follows:

Primitive types, such as Byte, Int32, Double, and String

Arrays

Data type conversion

C H A P T E R 5 T H E . N E T F R A M E W O R K C L A S S L I B R A R Y

195

Attributes

Delegates

Enums

Events

Exceptions

Garbage collection

Math

Operating system information

Random numbers

As you can see, you have already covered most of these areas in previous chapters.

Normally, a developer would allow garbage collection to be handled automatically by the CLR, because it’s a well-tuned process. For some applications, there might be occasions when garbage collection simply doesn’t run often enough or at the times wanted by the developer. For these cases, the .NET Framework class library provides the System::GC class. This class doesn’t allow the programmer the ability to change the garbage collection process, but it changes the triggering process and helps determine when memory is garbage collected. As a C++/CLI developer, you will probably have little need for the System::GC class given that you now have deterministic cleanup at your disposal. Other

.NET languages are not so lucky.

The Math class is an important class that I haven’t yet covered. It’s made up of a set of static data type overloaded member methods such as Abs(), Exp(), Max(), and Sin(). These methods are easy to use. For example, to find the square root of a number, simply code the following:

double val = 16;

double root = System::Math::Sqrt( val );

Another class that can come in handy is System::OperatingSystem. This class provides information such as the version and platform identifier. The System::Version class is used to hold the fourpart version (Build, Major, Minor, and Revision) used by the .NET Framework.

Because I am a games program developer at heart, one of the first classes I went in search of was the random-number generator. System::Random provides random numbers in both integer and floating-point formats.

System::Random ^rand = gcnew System::Random();

int intRandomNumber = rand->Next(1, 10); // between 1 and 10 inclusive double doubleRandomNumber = rand->NextDouble(); // between 0.0 and 1.0

System::Collections

There are, in fact, three sets of collections available to the .NET Framework programmer:

System::Collections, System::Collections::Specialized, and System::Collections::Generic. As the namespaces suggest, the first set contains standard collection types, the second contains collection types with a more specific purpose, and the third set contains collections specifically targeting the new generic class introduced in the .NET Framework version 2.0. You will find the more common and frequently used System::Collections in the mscorlib.dll assembly, whereas the

System::Collections::Specialized and System::Collections::Generic are in the system.dll assembly. Because collections are an integral part of most .NET software development, Chapter 7 goes

into many of these collections in much greater detail.

196 C H A P T E R 5 T H E . N E T F R A M E W O R K C L A S S L I B R A R Y

Table 5-1 shows you at a glance what collection types are found in the System::Collections namespace.

Table 5-1. Collection Types Found Within System::Collections

Collection

Description

ArrayList

An array that grows dynamically

BitArray

An array of bit values (either 1 or 0)

Hashtable

A collection of key/value pairs organized based on a hash code of the key

Queue

A collection of first-in-first-out objects

SortedList

A collection of key/value pairs sorted by key and accessible by either key or

 

index value

Stack

A collection of first-in-last-out objects

 

 

Table 5-2 lists all the collection types that you will find in System::Collection::Specialized. As you can see, you will probably use these collections less often, but the .NET Framework class library is nice enough to provide them if you ever end up needing to use one of them.

Table 5-2. Collection Types Found Within System::Collections::Specialized

Collection

Description

BitVector32

A small collection that will represent Boolean or small integers within

 

32 bits of memory

HybridDictionary

A collection that switches from a list dictionary when small to a hash

 

table when larger

ListDictionary

A singular link list recommended for lists of ten objects or less

NameValueCollection

A collection of string key/value pairs organized on the string key and

 

accessible by either string key or index

StringCollection

A collection of strings

StringDictionary

A hash table with the key strongly typed to be a string

 

 

Table 5-3 lists all the collections that you will find in System::Collections::Generic. Most likely, as you become more familiar with generics, these collections will become your primary choice.

Note After claiming that the .NET Framework strictly adheres to the CLS rules, Microsoft goes ahead and makes me a liar. System::Collections::Generic classes are not CLS compliant. Personally, I think the CLS rules will be expanded to include generics, but we shall see.

C H A P T E R 5 T H E . N E T F R A M E W O R K C L A S S L I B R A R Y

197

Table 5-3. Collection Types Found Within System::Collections::Generic

Collection

Description

Collection<T>

A base class for generic collections from which users are urged to

 

derive their own specialized container classes.

Dictionary<K,V>

A collection of key/value paired generic objects that are organized

 

based on the key and retrieved as a KeyValuePair<K,V> struct.

KeyedCollection<K,V>

A base class for generic collections using key/value pairs from

 

which users are urged to derive their own specialized container

 

classes.

LinkedList<T>

A doubly (forward and backward) linked list generic objects.

List<T>

An array of generic objects that grows dynamically.

Queue<T>

A collection of first-in-first-out generic objects.

ReadOnlyCollection<T>

A base class for a generic read-only collection from which users

 

are urged to derive their own specialized container classes.

 

A collection that is read-only is simply a collection with a wrapper

 

that prevents modifying the collection.

SortedDictionary<K,V>

A collection of key/value paired generic objects that are sorted

 

based on the key.

Stack<T>

A collection of first-in-last-out generic objects.

 

 

System::Data

The System::Data namespace is the root for all ADO.NET classes found in the .NET Framework class library. ADO.NET is the data access technology written for the .NET Framework and replaces the use of ADO where it is important to remain entirely within .NET. Accessing a database is a very common practice in software development, so you might think that it would be included in the mscorlib.dll default assembly, but you would be wrong. You need to reference two different assemblies. The first is the System.Data.dll assembly, which makes sense now that you know that it’s a separate assembly. The second is the System.Xml.dll assembly. I go into detail about why this assembly is needed in Chapter 12. A simple reason is that ADO.NET uses a lot of XML and exposes member methods that use XML. To include these assemblies, if you don’t recall, simply add these lines to the top of your source:

#using <System.data.dll> #using <System.Xml.dll>

The System::Data namespace comprises most of the classes that make up the ADO.NET architecture. The classes that represent the specific databases to which ADO.NET will connect are missing. These classes are known in ADO.NET-speak as data providers. Currently, ADO.NET supports multiple data providers. The data providers found in the System::Data namespace are the following:

System::Data::SqlClient: For Microsoft SQL Server database access

System::Data::SqlClientCe: For Microsoft SQL Server CE Edition database access

System::Data::Odbc: For ODBC database access

System::Data::OleDb: For OLE DB database access

System::Data::OracleClient: For Oracle database access