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

C# ПІДРУЧНИКИ / c# / MS Press - Msdn Training Programming Net Framework With C#

.pdf
Скачиваний:
173
Добавлен:
12.02.2016
Размер:
16.87 Mб
Скачать

Module 7: Strings, Arrays, and Collections

49

 

 

 

public static void printTable(Hashtable table) { Console.WriteLine ("Current list of employees:\n"); Console.WriteLine ("ID\tName");

Console.WriteLine ("--\t----"); foreach (DictionaryEntry d in table) {

Console.WriteLine ("{0}\t{1}", d.Key, d.Value);

}

}

}

The preceding code example displays the following output or similar output to the console:

Current list of employees:

ID

Name

--

----

1254

Brian

6839

Seth

3948

Rajesh

1930

Lakshan

0123

Jay

0569

Brad

9341

Kristian

Search for employee by key, enter ID ==-> 111

Employee 111 not found.

Search for employee by value, enter name ==-> Jay

Found Jay in

the list.

Current

list

of employees:

ID

Name

 

--

----

 

1254

Brian

 

6839

Seth

 

3948

Rajesh

1930

Lakshan

0123

Jay

 

0569

Brad

 

9341

Kristian

Remove employee by key, enter ID ==-> 9341

Current

list

of employees:

ID

Name

 

--

----

 

1254

Brian

 

6839

Seth

 

3948

Rajesh

1930

Lakshan

0123

Jay

 

0569

Brad

 

Press Return

to exit.

50

Module 7: Strings, Arrays, and Collections

SortedList

Topic Objective

To explain how arrays are used in a SortedList and how to create, initialize, and access a SortedList. This topic is very important because its contents are required for the lab.

Lead-in

A SortedList maintains two arrays internally to store entries to the list: one array for the keys, and another array for the associated values.

!SortedList Maintains Two Arrays for Entries

#One array for the keys and another array for the associated values

SortedList mySL = new SortedList();

SortedList mySL = new SortedList();

// Add an entry with a key = "First" and a value = 1 // Add an entry with a key = "First" and a value = 1 mySL.Add("First", 1);

mySL.Add("First", 1);

// Increment the value of the entry whose key = "First" // Increment the value of the entry whose key = "First" mySL["First"] = (Int32)mySL["First"] + 1;

mySL["First"] = (Int32)mySL["First"] + 1;

!Count Property – Number of Elements in the SortedList

!Sorted Using a Specific IComparer Implementation or According to the Key's IComparable Implementation

!Printing the Keys and Values of a SortedList

for ( int i = 0; i < myList.Count; i++ ) { for ( int i = 0; i < myList.Count; i++ ) { Console.WriteLine( "\t{0}:\t{1}",

Console.WriteLine( "\t{0}:\t{1}", myList.GetKey(i), myList.GetByIndex(i) ); } myList.GetKey(i), myList.GetByIndex(i) ); }

*****************************ILLEGAL FOR NON-TRAINER USE******************************

For Your Information

You should carefully cover the SortedList class, the Add method, and the [ ] Operator because they are used in the lab.

A SortedList maintains two arrays internally to store entries to the list: one array for the keys, and another array for the associated values. An entry is a key-and-value pair. A SortedList implements the IDictionary, IEnumerable,

ICollection, and ICloneable interfaces.

The Count property gets the number of elements that are contained in the SortedList. The Add method is used to add an entry to the SortedList. The [ ] Operator is used to modify the value of an entry with the specified key.

You can sort the keys of a SortedList according to an IComparer implementation that is specified when the SortedList is instantiated or according to the IComparable implementation that is provided by the keys themselves. In either case, a SortedList does not allow duplicate keys.

Operations on a SortedList tend to be slower than operations on a Hashtable because of the sorting. However, the SortedList offers more flexibility by allowing access to the values through the associated keys or through the indexes.

A key cannot be a null reference, but a value can be a null reference. Indexes in the SortedList collection are zero-based.

Module 7: Strings, Arrays, and Collections

51

 

 

 

The following example shows how to create a SortedList, add an entry, modify an entry’s value, and print out the SortedList’s keys and values.

using System;

using System.Collections;

public class SamplesSortedList {

public static void Main() {

//Create and initialize a new SortedList. SortedList mySL = new SortedList(); mySL.Add("First", 1);

mySL.Add("Second", 2); mySL.Add("Third", 3);

//Display the properties and values of the SortedList. Console.WriteLine( "mySL" );

Console.WriteLine( " Count: {0}", mySL.Count ); Console.WriteLine( " Capacity: {0}", mySL.Capacity ); Console.WriteLine( " Keys and Values:" ); PrintKeysAndValues( mySL );

//increment the value of the entry whose key is "Third" mySL["Third"] = (Int32)mySL["Third"] + 1; PrintKeysAndValues( mySL );

}

public static void PrintKeysAndValues( SortedList myList ){ Console.WriteLine( "\t-KEY-\t-VALUE-" );

for ( int i = 0; i < myList.Count; i++ ) { Console.WriteLine( "\t{0}:\t{1}",

myList.GetKey(i), myList.GetByIndex(i) );

}

Console.WriteLine();

}

}

The preceding code example displays the following output to the console:

mySL

Count: 3

Capacity: 16 Keys and Values:

-KEY- -VALUE- First: 1 Second: 2 Third: 3

-KEY- -VALUE-

First: 1

Second: 2

Third: 4

52

Module 7: Strings, Arrays, and Collections

Collection Usage Guidelines

Topic Objective

To distinguish between collections and arrays and explain when collections are used.

Lead-in

Arrays and collections are used similarly, but they perform differently.

!Use a Collection instead of an Array:

#When Add, Remove, or other methods for manipulating the set of objects are supported. This scopes all related methods to the collection

#When you want to provide a read-only set of objects. System.Array objects are always writable

-You can add read-only wrappers around internal arrays

!Use Collections to Avoid Inefficiencies

#In the following code, each call to the myObj property creates a copy of the array. As a result, 2n+1 copies of the array are created:

for (int i = 0; i < obj.myObj.Count; i++) for (int i = 0; i < obj.myObj.Count; i++)

DoSomething(obj.myObj[i]);

DoSomething(obj.myObj[i]);

*****************************ILLEGAL FOR NON-TRAINER USE******************************

Class library designers sometimes need to decide when to use an array and when to use a collection. Arrays and collections have similar usage models, but they differ somewhat in performance.

Collections vs. Arrays

When Add, Remove, or other methods for manipulating the collection are supported, use a collection, instead of an array. Using a collection scopes all related methods to the collection.

Also, use collections to add read-only wrappers around internal arrays.

System.Array objects are always writable.

Array Valued Properties

Use collections to avoid code inefficiencies. In the following code example, each call to the myObj property creates a copy of the array. As a result, 2n+1 copies of the array will be created in the following loop:

for (int i = 0; i < obj.myObj.Count; i++) DoSomething(obj.myObj[i]);

Module 7: Strings, Arrays, and Collections

53

 

 

 

Choosing A Collection Class

Choosing the right Collections class must be done carefully. Using the wrong collection can unnecessarily restrict how you use it.

Consider the following questions:

!Do you need temporary storage?

If yes, consider Queue or Stack.

If no, consider the other collections.

!Do you need to access the elements in a certain order, such as first-in-first- out, last-in-first-out, or randomly?

The Queue offers first-in, first-out access.

The Stack offers last-in, first-out access.

The rest of the collections offer random access.

!Do you need to access each element by index?

ArrayList and StringCollection offer access to their elements by the zero-based index.

Hashtable, SortedList, ListDictionary, and StringDictionary offer access to their elements by the key of the element.

NameObjectCollectionBase and NameValueCollection offer access to their elements either by the zero-based index or by the key of the element.

!Will each element contain just one value or a key-singlevalue pair or a keymultiplevalues combination?

One value: Use any of the collections based on IList.

Key-singlevalue pair: Use any of the collections based on IDictionary.

Key-multiplevalues combination: Consider using or deriving from the

NameValueCollection class in the Collections.Specialized namespace.

!Do you need to sort the elements differently from how they were entered?

Hashtable sorts the elements by the hash code of the key.

SortedList sorts the elements by the key, based on an IComparer implementation.

ArrayList provides a Sort method that takes an IComparer implementation as a parameter.

!Do you need fast searches and retrieval of information?

ListDictionary is faster than Hashtable for small collections of ten items or less.

!Do you need collections that accept only strings?

StringCollection (based on IList) and StringDictionary (based on IDictionary) are in the Collections.Specialized namespace.

54

Module 7: Strings, Arrays, and Collections

Type Safety and Performance

Topic Objective

To discuss runtime casting for type safety and the effects of runtime casting and boxing and unboxing on performance.

Lead-in

The System.Collections classes are generic collections, which ignore their items’ true types. Generic collections allow classes to be used for items of any type.

!System.Collections Items Require a Runtime Object Cast

!Drawbacks of Runtime Casting

#Type errors found at runtime, rather than at compile time

#Runtime overhead of casting

#Runtime overhead of boxing/unboxing operations for value types

!Type-Specific Collection Classes Can Eliminate Runtime Casting

#System.Collections.Specialized namespace contains stringspecific collections

#Create your own type-specific collection class by inheriting from a System.Collections class and adding type-specific members

!Ways to Reduce Boxing and Unboxing Operations of Value Types

#Encapsulate value types in a class

#Manipulate value types through interfaces

*****************************ILLEGAL FOR NON-TRAINER USE******************************

The System.Collections classes are generic collections, which ignore their items’ true types. Generic collections allow classes to be used for items of any type.

Drawbacks of Runtime Casting

The System.Collections classes have properties and methods that manipulate the collection’s items through the item’s System.Object base type. The class’s members take and return parameters of type System.Object. For example,

IEnumerator.Current returns a System.Object instance.

This use of an object’s base class requires casting a runtime object to obtain the true type of the object. Casting System.Object instances at run time has two drawbacks:

!Collection operations with invalid parameter or return types are not flagged at compile time.

If the cast is invalid, the problem is only detected at run time when an

InvalidCastException is thrown.

!Such casting hurts runtime performance because the .NET runtime must perform type-checking.

In addition, in the case of a collection of value types, such as an int, casting to and from System.Object results in boxing and unboxing operations that further impair performance.

The ideal solution to these two drawbacks would be a language mechanism that automatically generates a type-specific version of the System.Collections classes that is similar to the C++ template class mechanism. For example, if you declared an ArrayList<int>, this object would store int values directly, without casting and without boxing. This feature is not implemented in the first version of C#; however, it may be implemented in a later version.

Module 7: Strings, Arrays, and Collections

55

 

 

 

The System.Collections classes provide a simple and powerful way to implement collections. Carefully evaluate whether the use of these classes in your programs imposes a significant enough performance penalty to warrant taking the further action that is described in the following sections.

Strongly-Typed Collections

One way to provide compile-time type-checking and improve the performance of collection code is to use strongly-typed collections. The System.Collections.Specialized namespace contains string-specific collection classes, as described in the following table.

Class

Description

NameValueCollection

Represents a sorted collection of associated String keys

 

and String values that can be accessed with the hash

 

code of the key or with the index.

StringCollection

Represents a collection of strings.

StringDictionary

Implements a hash table with the key strongly-typed to

 

be a string, rather than an object.

StringEnumerator

Supports a simple iteration over a StringCollections.

Creating Custom Collection Classes

You can also create your own strongly-typed collection by creating your own custom collection class. Your class can reuse System.Collections functionality by inheriting from the appropriate System.Collections class. You create the type-specific class with methods and properties whose parameters and return types are type-specific.

By using C#’s explicit interface implementation mechanism, which is discussed in Module 6, “Working with Types,” in Course 2349B, Programming with the Microsoft .NET Framework (Microsoft Visual C#.NET), a class can implement both non-interface and interface members of the same name. Explicit interface method implementations are frequently used when you implement such interfaces as IEnumerable, IEnumerator, ICloneable, IComparable, ICollection, IList, and IDictionary. By having both sets of members, clients that expect type-specific or System.Object parameters and return values can use the custom class.

Techniques for Handling Boxing and Unboxing

Instead of creating a type-specific collection class, you can remove the overhead of boxing and unboxing by using a reference type, rather than a value type, for the items in a collection. To accomplish this, you can wrap a value type in a class, as shown in Module 6, Course 2349B, Programming with the Microsoft .NET Framework (Microsoft Visual C# .NET).

In some cases, you can reduce boxing and unboxing by using interfaces. Value types can implement interfaces, but because interfaces are referenced types, you can only have an interface reference to a boxed value type.

You can define an interface for your value type that has the methods and properties that are needed to manipulate the value type. The value type instance must still be boxed when it is inserted into a generic System.Collections object, but your code will be able to manipulate the item’s value through its interface without unboxing the item.

56

Module 7: Strings, Arrays, and Collections

For example, in the case of a collection of integer values where you want to be able to add an integer to an element’s value, you can have your value type implement an interface, as in the following code:

interface IAdd

{

void Add(int amount);

}

struct IntStruct: IAdd

{

int number;

public IntStruct(int number) { this.number = number;

}

public int Number {

get { return(number);}

}

public void Add(int amount) { number += amount;

}

public override string ToString() { return(number.ToString());

}

}

Module 7: Strings, Arrays, and Collections

57

 

 

 

Lab 7: Working with Strings, Enumerators, and Collections

*****************************ILLEGAL FOR NON-TRAINER USE******************************

Objectives

After completing this lab, you will be able to:

!Create an application that parses and formats strings.

!Create an application that uses SortedList collection objects.

Lab Setup

Starter and solution files are associated with this lab. The starter files are in the folder <install folder>\Labs\Lab07\Starter, and the solution files are in the folder <install folder>\Labs\Lab07\Solution.

Scenario

In this lab, you are provided with a Visual Studio .NET console application as a starting point. The application, named WordCount, parses a test string into words and then determines the number of unique words and the number of times each word occurs. The results of this analysis are formatted and displayed on the console.

The application is a modified version of the .NET Framework SDK sample,

Word Count.

Estimated time to complete this lab: 60 minutes

58

Module 7: Strings, Arrays, and Collections

Exercise 1

Sorting Words Alphabetically

In this exercise, you will create a class that breaks up the test string into words and then stores each word and the number of its occurrences in a SortedList. By default, the sort order will be based on the alphabetical ordering of the word keys.

!Modify the WordCount class to sort words alphabetically

1.Open the WordCount project in the starter directory by using Visual Studio

.NET.

2.Open the WordCount.cs file.

3.In the WordCounter class, create a member named wordCounter that is an instance of the SortedList class.

4.Create a read-only property named UniqueWords that returns the number of items in wordCounter.

5.Create a public method named GetWordsAlphabeticallyEnumerator that takes no arguments and returns a wordCounter enumerator object of type

IDictionaryEnumerator.

6.Create a public method named CountStats that takes two out parameters of type Int64 named numWords and numChars and returns a Boolean.

7.Implement the CountStats method to break up the test string, create the alphabetically sorted list, and return the word count statistics.

a.Initialize the CountStats method’s out parameters to 0.

b.Use the String.Split method to break up testString into individual words that are stored in an array of type string named Words.

c.Assign to the out parameter numWords the number of words that are obtained in step 7.b.

d.For each non-empty string in the array Words:

i.Add the number of characters in the word string to numChars.

ii.If wordCounter does not already contain the string, add a new entry whose key is the string and whose value is 1. The value represents the number of occurrences of the word. Otherwise, increment by one the value of the existing entry.

Tip For information about and examples of the IDictionary methods named Add and Contains, see Dictionaries and Demonstration: Hashtable in this module. For an example of how to modify the value of an entry by using the [] Operator, see SortedList in this module.

iii. Return true.

Соседние файлы в папке c#