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

Beginning ASP.NET 2.0 With CSharp (2006) [eng]

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

Chapter 9

This declares a string array called Names, but it’s an empty array — it doesn’t actually create any spaces for the array elements. To do this, you use the new keyword, so to store five names you would change the declaration to the following:

string[] Names = new string[5];

One thing to note is that the index for arrays starts at 0. So this array has 0, 1, 2, 3, and 4, which gives five entries. The bounds of the array are 0 to 4.

Accessing array values, either to read or assign values, follows the same rules, with the addition of the square brackets. Within the square brackets, you put the index number of the element required. For example:

Names[0] = “Dave”;

Names[4] = “Dan”;

NameTextBox.Text = Names[4];

In this example, Dave is the first entry and Dan is the fifth entry. The entries between will be empty because no values have been set for them.

Trying to access an element that doesn’t exist (anything above 4 in this example) will generate an exception with the message “Index was outside the bounds of the array.”

Arrays can also be dynamically sized when declared:

string[] Names = {“Dave”, “Chris”, “Chris”, “John”, “Dan”};

Here the array has five elements with the first being assigned to Dave, the second to Chris, and so on. The curly brackets enclose the list of items for the array.

Multi-Dimensional Arrays

Arrays aren’t limited to one dimension, so you can replicate that spreadsheet type of storage. For example, to use an array to store first and last names, you could do this:

string[,] Names = new string[5, 2]; Names[0,0] = “Dave”;

Names[0,1] = “Sussman”;

Names[1,0] = “Chris”;

Names[1,1] = “Hart”;

...

Names[4,0] = “Dan”; Names[4,1] = “Maharry”;

Here the declaration separates the dimensions by a comma. The number of elements in each dimension is included in the variable declaration, so the first dimension has five elements (0–4), and the second has two (0–1). This gives you storage like so:

298

Code

 

0

1

0

Dave

Sussman

1

Chris

Hart

 

...

 

4

Dan

Maharry

A 4-by-4 array (four rows, four columns) would be declared as follows:

string[,] MyArray = new string[3, 3];

Adding another dimension is as simple as adding a comma and another number. So a three-dimensional array, with four elements in each dimension would be:

string[,,] MyArray = new string[3, 3, 3];

Like single dimensional arrays, multi-dimensional ones can also be initialized at declaration time:

string[,] Names = {{“Dave”, “Sussman”}, {“Chris”, “Hart”}};

Like the single dimension, curly brackets are used to surround the entries, but there are two sets of brackets, one for each dimension: the outer set for the first dimension, and the inner set for the second. The first names, Dave and Chris, are placed in the first dimension, and the last names, Sussman and Hart, are placed in the second dimension. So this is the same as:

string[,] Names = new string[2, 2]; Names[0,0] = “Dave”;

Names[0,1] = “Sussman”;

Names[1,0] = “Chris”;

Names[1,1] = “Hart”;

Which style you use is a matter of personal preference, because there’s no real difference between them.

Collections

Another way of storing multiple items is to use collections. Collections differ from arrays in that they are always dynamically allocated, which makes them more suitable for situations where the

amount of data changes frequently. There are different collections for different purposes, stored in the System.Collections namespace (more on namespaces later), including the following:

ArrayList provides a general collection for objects.

Hashtable provides storage for key/value pairs. A key/value pair is simply the storage of values, which can then later be identified by a key. In array terms, the key is the index of the array element, but a Hashtable allows the key to be non-numeric.

Queue provides a first-in, first-out collection, which means that items are taken off the queue in the same order in which they were placed onto it, just like a real queue — the person who arrives first gets served first.

299

Chapter 9

SortedList provides ordered storage for key/value pairs.

Stack provides a last-in, first-out collection, where items are taken off the stack in the reverse order in which they were placed onto it. Think of a stack of plates — the last one put onto the stack is the first off.

StringCollection provides a collection of strings.

There are other collections, but these are the ones you’ll probably use most frequently. Data is added to collections by calling an Add method, the parameters of which depend upon the collection being used. For the StringCollection, you simply supply the string to be added. For example:

StringCollection Names = new StringCollection();

Names.Add(“Dave”);

Names.Add(“Chris”);

To access the entries, you use the same method as an array:

NameTextBox.Text = Names[0];

This would return Dave, because the names are added in numerical order.

A HashTable is different because the index isn’t numerical, but rather string-based. With a StringCollection, the index is a number, and it is assigned automatically, in order of the items added. With a HashTable, you have to specify the key as well as the item you want to add. For example:

HashTable Names = new Hashtable();

Names.Add(“Dave”, “Sussman”);

Names.Add(“Chris”, “Hart”);

In this example, the first parameter is the key, and the second is the value, which leads to them being called key/value pairs. You can also add entries without using the Add method:

Names[“John”] = “Kauffman”;

There’s no real difference between using and not using the Add method, although it’s best to use Add if only because it clarifies what is being done. Without the Add method, the code looks more like an assignment, so you aren’t completely sure whether a new item is being added or if an existing one is being modified.

To access the entries you use the key:

NameTextBox.Text = Names(“Chris”)

One important point about using HashTables is that the keys must be unique. So in the preceding example, a HashTable wouldn’t really be suitable for storing the author names, because two of the authors have the same first name. So this code would fail:

HashTable Names = new Hashtable();

Names.Add(“Chris”, “Ullman”);

Names.Add(“Chris”, “Hart”);

300

Code

An exception would be raised on the second Add line, because the key has already been used.

Collections, and arrays for that matter, aren’t only useful for storing native types such as strings or integers. They can also be used to store custom classes, which you will look at later in the chapter. The following Try It Out, however, puts your knowledge of arrays and collections to use.

Try It Out

Working with Arrays and Collections

1.Create a new Web Form, called ArraysCollections.aspx.

2.Add a TextBox, a Button, a ListBox, and another TextBox to the form.

3.For the text boxes, set the TextMode property to MultiLine, the Columns property to 50, and the Rows property to 5. When finished, it should look like Figure 9-4.

Figure 9-4

4.Enter the following code into the Click event for the button:

string splitChars = “ “; string[] words;

words = TextBox1.Text.Split(splitChars.ToCharArray());

ListBox1.Items.Clear();

for (int wordIndex = words.Length - 1; wordIndex >= 0; wordIndex--)

{

ListBox1.Items.Add(words[wordIndex]);

}

string paragraph = string.Empty;

foreach (ListItem word in ListBox1.Items)

{

paragraph += word.Value + “ “;

}

TextBox2.Text = paragraph;

301

Chapter 9

5.Save the files, and set ArraysCollections.aspx as the start page.

6.Press F5 to run the page and enter Wrox United are the best into the first text box.

7.Press the button and you will see the screen shown in Figure 9-5.

Figure 9-5

You can see that the sentence in the first text box has been split into its component words, those words have been entered into the list box in reverse order, and then the words have been combined into the second text box. The following section explains how this works.

How It Works

The first two lines of the code simply define variables. The first, splitChars, is a string containing the characters that will be used to split the sentence, and the second, words, is an array of strings:

string splitChars = “ “; string[] words;

Next, the sentence entered into the text box is split into an array, using the Split method. Although it looks like Split is a method of the Text property, remember that the Text property returns a String — so Split is a method of the String class. The parameter passed into the string is not the splitChars variable itself, but splitChars converted to a character array (using the ToCharArray method). This is because a character array is the required type for the Split method, which allows a great deal of flexibility in splitting strings:

words = TextBox1.Text.Split(splitChars.ToCharArray());

At this stage, the words array now contains a separate entry for each word in the sentence, ready for addition into the list box. Before the words are added to the list, the existing Items collection is cleared, which stops the list from getting ever bigger if the button is clicked multiple times. Then you loop through the words array, but loop backwards, adding each word into the list:

ListBox1.Items.Clear();

for (int wordIndex = words.Length - 1; wordIndex >= 0; wordIndex--)

302

Code

{

ListBox1.Items.Add(words[wordIndex]);

}

Don’t worry too much about the exact syntax of the looping — you get to that later in the chapter.

After the words are in the list, they can be removed again, into another string. This has an initial value that might seem unusual — String.Empty — but this is quite a common thing for initializing strings:

string paragraph = String.Empty;

String.Empty is a special value that indicates that the string is empty. This is different from a string assigned to “”, which has a value, albeit a string of zero length that doesn’t contain any characters. The reason for having a distinction between a zero-length string and an empty string is that it allows you to detect whether the string has been set or changed from its initial value. One of the reasons for declaring an initial value is that without it you get a warning in VWD, but on a later line, indicating that the paragraph variable is being used before it has been set. In this case, it doesn’t matter, but reducing warnings in VWD means it’s easier to spot warnings and errors that do matter.

Now loop through the Items collection of the list box, and the Items collection contains ListItem objects. The Value of each ListItem is simply appended to the paragraph string, along with a space:

foreach (ListItem word in ListBox1.Items)

{

paragraph += word.Value + “ “;

}

Finally, the paragraph is displayed in the second text box:

TextBox2.Text = paragraph;

This may seem an overly lengthy way to reverse the words in a sentence, but the point of the exercise is to show that there are different ways of working with arrays and collections.

Deciding Whether to Use Arrays or Collections

There are pros and cons of using both arrays and collections, and the decision of which to use can sometimes be confusing. In general, if the number of elements isn’t going to change, an array is best — it’s efficient and fast, and it provides easy access to the elements. If you need to change the number of elements, or insert elements between others, then a collection is best.

Both arrays and collections can, like some of the data objects, be used for data binding. For example, the Wrox United shop could have a list of delivery methods in a drop-down list:

string[] delivery = {“Post”, “Courier”, “International”} DeliveryDropDownList.DataSource = delivery; DeliveryDropDownList.DataBind();

Here the array is simply used as the source to which to bind the list. Collections can also be used in this manner. Data binding was covered in Chapter 7.

303

Chapter 9

Enumerations

Enumerations are a custom data type where the value can be one of a number of values. This is easier to see with an example, so take a look at the Calendar control. This is a complex control and has many properties to allow its look to be changed, one of which is the DayNameFormat (see Figure 9-6).

Figure 9-6

The format must be one of five values — Full, Short, FirstLetter, FirstTwoLetters, and Shortest — and no other, so there needs to be a way of ensuring only these values can be selected. This is where enumerations come in because enumerations restrict the variable to a set of known values. The syntax for creating an enumeration is as follows:

public enum EnumerationName

{

enumeration values

}

What this does is declare a new type, with the name of the type being whatever name you give it as EnumerationName. This type is a special type where the values can only be one of those in the supplied list. For example, the DayNameFormat is an enumeration, which has been created like so:

public enum DayNameFormat

{

Full,

[Short],

FirstLetter,

FirstTwoletters, Shortest

};

The values used in the enumeration are separated by a comma. Because this is a new type, it can be used in variable declarations:

304

Code

DayNameFormat dayFormat;

dayFormat = DayNameFormat.FirstLetter;

This declares a new variable of the enumeration type — DayNameFormat. Then it assigns a value to the variable, and the value assigned is one of the defined values. This shows as the enumeration name and value separated by a period. What’s great is that you get IntelliSense, so you can pick from a list of the known values when assigning the variable.

Enumerations provide a way to have a human-readable value associated with a number. In the preceding example, no numbers are explicitly assigned, so they are created automatically, starting at 0. So here, Full would be 0, Short would be 1, and so on. The Short value was enclosed within square brackets when it was declared because Short is also a data type. Using the square brackets tells .NET that this is the custom name rather than the data type. If you don’t want to use the default numbers for the values, you can specify them yourself. For example:

public enum DeliveryType

{

Post,

Courier = 4, International

};

Here, the Post would be 0 and the Courier has an explicit value of 4. Because International doesn’t have an explicit value, automatic numbering starts again, at the last number used, so it would have a value of 5.

Enumerations are used when you need to allow one of a limited number of values for a selection. It’s used extensively in the ASP.NET server controls to allow only selected values, often allowing the behavior to change. The TextBox, for example, has a TextMode property that can be one of SingleLine, MultiLine, or Password. How the TextBox is displayed changes depending on which value is selected. When creating code yourself, for the day-to-day running of an application, there is perhaps less use for enumerations (the Wrox United site doesn’t use any Enums), but they can be useful, perhaps when you’re building central libraries of code.

Constants

Constants are another way to provide a human-readable form for values, but unlike enumerations, constants are a single value only and as their name suggests, they are constant and never change. This is useful for situations where you need to use a fixed value. Using a constant means you can give that value a name and use the name throughout the code. The value is defined once, meaning it is easy to change, and because the readable name is used throughout the code, the code becomes more maintainable.

Even if the value is only used once, it’s sensible to use constants because they provide a way to centralize this type of fixed value. The syntax for a constant is as follows:

private const Type ConstantName = Value;

const is what defines this as a constant, and private is how visible the constant is — you look at this later in the chapter. The rest of the declaration is just like any other variable, the difference being that the value is constant, and therefore cannot be changed.

305

Chapter 9

For example, in the Wrox United web site there is a shopping cart to store items bought from the shop. Members of the fan club receive a 10% discount, so this value is stored as a constant:

private const single MemberDiscountPercentage = 0.1;

When the total price of the order is calculated this constant can be used, just like any other variable:

MemberDiscount = SubTotal * MemberDiscountPercentage;

Total = SubTotal – MemberDiscount;

You look at the implementation of the shopping cart later in the chapter.

Statements

Statements are where the real action of code is, allowing you to control the program. You have seen many statements in code already in the book, and at the time it wasn’t convenient to explain what they meant or how they worked. Now is that time, because statements are what drive your code. Statements are what allow you to structure your code, to make decisions, and to repeat actions a number of times. For example, to make a decision, you use the if statement, which can be used to allow the code to react to external criteria. Take the Wrox United checkout page, where members of the fan club receive a discount. This is done with a decision, which goes something like this:

if (person is a member of the fan club)

{

give that person a discount

}

The if is the C# statements that test a condition — or ask a question. Think of the program as a person deciding what to do. The code within the curly braces is the code that is run if the condition is true.

For repeating tasks, there are statements called loops, and there are different types of loops for different tasks. Some (for) repeat a fixed number of times, whereas others (while) repeat until a condition is met, or while a condition is true.

Before conditions and loops can be examined in more detail, some other topics need to be covered.

Operators

The first thing to look at is operators, which are how values are manipulated. If you can remember back to your math lessons in school, this will be familiar. You’ve already seen the assignment operator, the equals sign (=), in action earlier in the chapter, and this simply assigns a value to a variable. The next several sections discuss how the remaining operators allow you to carry out predefined operations.

Concatenation

Concatenation is used to join strings. For example, consider if you had the first and last names in a multidimensional array (as shown when you looked at arrays), and you wanted to have a single variable with the full name. You would use the concatenation operator, the plus sign (+), to do this:

string FullName;

FullName = Names[0,0] + Names[0,1];

306

Code

This takes the last name and joins it to the end of the first name. However there is no space separating them, so the code could be:

FullName = Names[0,0] + “ “ + Names[0,1];

Now you have two concatenations taking place. First a space is added and then the last name. You could have also used another form of the assignment operator:

FullName = Names[0,0];

FullName += “ “;

FullName += Names[0,1];

The use of += simply says take the variable on the right of the assignment and append to it the contents on the left. This also works with arithmetic operators, which are the subject of the next section.

Arithmetic Operators

Arithmetic operators allow you to perform arithmetic on variables: addition, subtraction, and so on. The following table displays the arithmetic operators:

Operator

Action

+

Addition

-

Subtraction

*

Multiplication

/

Division

%

Modulus

The standard mathematical operators are easy to understand — they add, subtract, multiply, and divide in the way you’d expect:

int n1

= 6;

Single

n2 = 14.3;

double

n3;

n3

= n1

+ n2;

// results in: 20.3

n3

= n2

– n1;

// results in: 8.3

n3

=

n1

/

n2;

//

results in:

0.41958

n2

=

n1

*

n2;

//

results in:

85.8

Modulus divides two numbers and returns the remainder. One of the classic uses for this is to test if a number is odd or even:

int n1;

n1

= 1

% 2;

// results in: 1

n1

= 2

% 2;

// results in: 0

n1

=

3

% 2;

// results

in:

1

n1

=

14 % 2;

// results

in:

0

307