Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C# 2008 Step by Step.pdf
Скачиваний:
26
Добавлен:
25.03.2016
Размер:
13.96 Mб
Скачать

350

Part III Creating Components

tree2.Insert(“Today”);

tree2.Insert(“I”);

tree2.Insert(“Hope”);

tree2.Insert(“You”);

tree2.Insert(“Are”);

tree2.Insert(“Feeling”);

tree2.Insert(“Well”);

tree2.Insert(“!”);

tree2.WalkTree();

}

These statements create another binary tree for holding strings, populate it with some test data, and then print the tree. This time, the data is sorted alphabetically.

11.On the Build menu, click Build Solution. Verify that the solution compiles, and correct any errors if necessary.

12.On the Debug menu, click Start Without Debugging.

The program runs and displays the integer values as before, followed by the strings in the following sequence:

!, Are, Are, Feeling, Hello, Hope, How, I, Today, Well, World, You, You

13.Press the Enter key to return to Visual Studio 2008.

Creating a Generic Method

As well as defining generic classes, you can also use the .NET Framework to create generic methods.

With a generic method, you can specify parameters and the return type by using a type parameter in a manner similar to that used when defining a generic class. In this way, you can define generalized methods that are type-safe and avoid the overhead of casting (and boxing in some cases). Generic methods are frequently used in conjunction with generic classes—you need them for methods that take a generic class as a parameter or that have a return type that is a generic class.

You define generic methods by using the same type parameter syntax that you use when

creating generic classes (you can also specify constraints). For example, you can call the following generic Swap<T> method to swap the values in its parameters. Because this func-

tionality is useful regardless of the type of data being swapped, it is helpful to define it as a generic method:

static void Swap<T>(ref T first, ref T second)

{

T temp = first; first = second; second = temp;

}

Chapter 18 Introducing Generics

351

You invoke the method by specifying the appropriate type for its type parameter. The following examples show how to invoke the Swap<T> method to swap over two ints and two strings:

int a = 1, b = 2; Swap<int>(ref a, ref b);

...

string s1 = “Hello”, s2 = “World”; Swap<string>(ref s1, ref s2);

Note Just as instantiating a generic class with different type parameters causes the compiler to generate different types, each distinct use of the Swap<T> method causes the compiler to generate a different version of the method. Swap<int> is not the same method as Swap<string>; both

methods just happen to have been generated from the same generic method, so they exhibit the same behavior, albeit over different types.

Defining a Generic Method to Build a Binary Tree

The preceding exercise showed you how to create a generic class for implementing a binary tree. The Tree<TItem> class provides the Insert method for adding data items to the tree. However, if you want to add a large number of items, repeated calls to the Insert method

are not very convenient. In the following exercise, you will define a generic method called InsertIntoTree that you can use to insert a list of data items into a tree with a single method

call. You will test this method by using it to insert a list of characters into a tree of characters.

Write the InsertIntoTree method

1.Using Visual Studio 2008, create a new project by using the Console Application template. In the New Project dialog box, name the project BuildTree. If you are us-

ing Visual Studio 2008 Standard Edition or Visual Studio 2008 Professional Edition, set the Location to \Microsoft Press\Visual CSharp Step By Step\Chapter 18 under your Documents folder, and select Create a new Solution from the Solution drop-down list. Click OK.

2.On the Project menu, click Add Reference. In the Add Reference dialog box, click the

Browse tab. Move to the folder \Microsoft Press\Visual CSharp Step By Step\Chapter 18 \BinaryTree\BinaryTree\bin\Debug, click BinaryTree.dll, and then click OK.

The BinaryTree assembly is added to the list of references shown in Solution Explorer.

3.In the Code and Text Editor window displaying the Program.cs file, add the following using directive to the top of the Program.cs file:

using BinaryTree;

This namespace contains the Tree<TItem> class.

352Part III Creating Components

4.Add a method called InsertIntoTree to the Program class after the Main method. This should be a static method that takes a Tree<TItem> variable and a params array of TItem elements called data.

The method definition should look like this:

static void InsertIntoTree<TItem>(Tree<TItem> tree, params TItem[] data)

{

}

Tip An alternative way of implementing this method is to create an extension method of the Tree<TItem> class by prefixing the Tree<TItem> parameter with the this keyword and defining the InsertIntoTree method in a static class, like this:

public static class TreeMethods

{

public static void InsertIntoTree<TItem>(this Tree<TItem> tree, params TItem[] data)

{

...

}

...

}

The principal advantage of this approach is that you can invoke the InsertIntoTree method directly on a Tree<TItem> object rather than pass the Tree<TItem> in as a parameter.

However, for this exercise, we will keep things simple.

5.The TItem type used for the elements being inserted into the binary tree must implement the IComparable<TItem> interface. Modify the definition of the InsertIntoTree method and add the appropriate where clause, as shown in bold type in the following code.

static void InsertIntoTree<TItem>(Tree<TItem> tree, params TItem[] data) where TItem :

IComparable<TItem>

{

}

6.Add the following statements shown in bold type to the InsertIntoTree method. These

statements check to make sure that the user has actually passed some parameters into the method (the data array might be empty), and then they iterate through the params list, adding each item to the tree by using the Insert method. The tree is passed back as the return value:

static void InsertIntoTree<TItem>(Tree<TItem> tree, params TItem[] data) where TItem : IComparable<TItem>

{

if (data.Length == 0)

throw new ArgumentException(“Must provide at least one data value”);

Chapter 18 Introducing Generics

353

foreach (TItem datum in data)

{

tree.Insert(datum);

}

}

Test the InsertIntoTree method

1.In the Main method of the Program class, add the following statements shown in bold type that create a new Tree for holding character data, populate it with some sample data by using the InsertIntoTree method, and then display it by using the WalkTree method of Tree:

static void Main(string[] args)

{

Tree<char> charTree = new Tree<char>(‘M’); InsertIntoTree<char>(charTree, ‘X’, ‘A’, ‘M’, ‘Z’, ‘Z’, ‘N’); charTree.WalkTree();

}

2.On the Build menu, click Build Solution. Verify that the solution compiles, and correct any errors if necessary.

3.On the Debug menu, click Start Without Debugging.

The program runs and displays the character values in the following order: A, M, M, N, X, Z, Z

4.Press the Enter key to return to Visual Studio 2008.

If you want to continue to the next chapter

Keep Visual Studio 2008 running and turn to Chapter 19. If you want to exit Visual Studio 2008 now

On the File menu, click Exit. If you see a Save dialog box, click Yes (if you are using Visual Studio 2008) or Save (if you are using Visual C# 2008 Express Edition) and save the project.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]