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

Visual CSharp .NET Programming (2002) [eng]

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

Figure 5.17: The assembly containing the class library now appears in the Selected Components pane.

The reference to the SybexC12.Baby class library has now been added to the project. If you open the Object Browser, you'll easily be able to find the Baby class members (Figure 5.18).

Figure 5.18: Once the reference has been added, the class members appear in the Object Browser.

The next step is to add some TextBoxes and Buttons to the form to use to invoke the members of the class library. Let's add TextBoxes for the baby name and age, a Button to set them, and a Get Sound button to get a representation of the noise often made by the baby object.

Instantiating an Object Based on the Class

Turning to the form code, the first step is to add a using directive that refers to the SybexC12 namespace. Next, we'll instantiate an object, in this case stored in a variable named myBaby, based on the Baby class:

...

using SybexC12;

...

public class Form1 : System.Windows.Forms.Form

{

...

Baby myBaby = new Baby();

...

Using a Class Method

It's a simple matter now to invoke the myBaby.GetSound method in the click event of the Get Sound button:

private void btnGetSound_Click(object sender, System.EventArgs e) { string msg = myBaby.GetSound();

MessageBox.Show(msg, "Hi from my Baby!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

}

Setting Fields and Properties

It's equally simple to set the Name field and Age property in the click event handler of the Set button:

private void btnSet_Click(object sender, System.EventArgs e) { myBaby.Age = Convert.ToInt16(txtAge.Text);

myBaby.Name = txtName.Text;

}

Wiring the Event

To wire the event, we first need to create a method in the form class with the same signature as the event delegate. This method will be executed when the event is raised. For example, we can simply display a message box in a method named Baby_OnBirthDay whose signature matches the event delegate:

private void Baby_OnBirthDay(object sender, System.EventArgs e) { MessageBox.Show("The Baby.OnBirthDay event was raised!",

"Happy, Happy Birthday to my baby!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

}

Next, in the form's constructor, the myBaby.OnBirthDay event is wired via the event delegate to the Baby_OnBirthDay method.

myBaby.OnBirthDay += new Baby.BirthDayEventHandler(this.Baby_OnBirthDay);

If you run the project and enter an age for the baby object that will trigger the event (for example, 1, since the initial value for the age is 0), you will see that the OnBirthDay event will be triggered, as shown in Figure 5.19.

Figure 5.19: The OnBirthDay event is raised when the age is changed.

Conclusion

Programming with C# and the .NET Framework means programming with classes. This chapter has covered a lot of ground and started you down the path of programming well with classes. But it is not an island! You'll find a great deal more about object-oriented programming in Chapter 8. In the meantime, it is back to basics: Chapter 6 explains the basic building blocks of the C# language.

Part III: Courante: The Dance

of the Language

Chapter 6: Zen and Now: The C# Language

Chapter 7: Arrays, Indexers, and Collections

Chapter 8: The Life of the Object in C#

Chapter 9: Everything Is String Manipulation

Chapter 6: Zen and Now: The C# Language

Overview

C# vocabulary: Identifiers and keywords

Manipulating values: Variables and constants

Types and type conversion

Commenting C# code

C# syntax: Operators and flow control

Structs

Exceptions

O, wonder!' exclaims Miranda in Shakespeare's play The Tempest. 'How many goodly creatures are there here! How beauteous mankind is! O brave new world that has such people in't!'

Our brave new world is, in fact, a brave new language: C#.

It has no 'creatures' in it. Nor, for that matter, does it have the pharmacopoeia of Aldous Huxley's famous dystopia, Brave New World.

C# does have things like types, operators, variables, and expressions, glued together using a distinctive syntax. O brave new language! The introduction of a new language is a rare event. While C# borrows from Java, C++, C, and even Visual Basic and Pascal, it is a truly new language-and, in the opinion of this author, quite wondrous.

Since C# is new, and since language and syntax are the blocks on which programs are built, it's especially important to pay attention to the rules of the language. This chapter reviews the nuts and bolts of the C# language.

Identifiers

Identifiers are names used to denote variables, constants, types, methods, objects, and so on. An identifier begins with a letter or an underscore and ends with the character just before the next white space.

C# identifiers are case sensitive. For example, the three variables deeFlat, DeeFlat, and DEEFLAT are all different, as running this click procedure will show:

private void btnClickMe_Click(object sender, System.EventArgs e) { string deeFlat = "deeFlat";

string DeeFlat = "DeeFlat"; string DEEFLAT = "DEEFLAT";

MessageBox.Show(deeFlat + " " + DeeFlat + " " + DEEFLAT, "Hello, Variables!", MessageBoxButtons.OK);

}

Microsoft suggests using 'camel notation' for identifiers used as names of variables. Camel notation means an initial lowercase letter followed by uppercase letters ('internal caps') for initial letters of subsequent words in the identifier-for example, deeFlat.

Pascal notation-an initial uppercase letter, with internal caps as needed-is supposed to be used for identifiers that represent method names and most other non-variable objects. In addition, an identifier used for a method should use a verb-noun combination to describe the purpose of the method-for example, GetColorValues.

For more on Microsoft's suggested identifier naming conventions, look up 'Naming Guidelines' using the Search feature in online help.

Note It's always good programming practice to use identifiers that clearly communicate the contents and/or nature of the variable or other object identified. Code that uses clear identifiers may be almost self-documenting. For more suggestions of this kind, see the 'Self-Documenting Code' section later in this chapter.

It is not legal to use an identifier that is also a C# keyword. (You'll find a list of C# reserved keywords in the next section.) If, for some really perverse reason, you must use a keyword as an identifier, you can preface the keyword with the @ symbol. For example, if cannot be used as an identifier (because it is a keyword), but @if can; this code snippet shows it employed as a string variable:

string @if = "@if";

MessageBox.Show(@if, "Hello, Variables!", MessageBoxButtons.OK);

For that matter, if you were really bound and determined to create an identifier like a keyword, you could simply vary the case. So If is a perfectly legal identifier-albeit an idiotic choice because it is similar to a keyword and so potentially confusing-because the keyword if is all lowercase.

Tip Visual Basic programmers, who are used to case insensitivity, may find that C#'s case sensitivity regarding identifiers leads to the introduction of bugs. Fortunately, these kinds of bugs are found pretty easily once you are on the watch for them, and paying attention

to the case of identifiers will become second nature shortly.

Keywords

Another way to think of a keyword is as a predefined reserved identifier. Table 6.1 shows the complete list of C# keywords.

 

 

Table 6.1: C# Keywords (Reserved Identifiers)

 

 

 

 

 

 

 

 

 

 

 

abstract

 

do

 

in

 

protected

 

true

 

 

 

 

 

 

 

 

 

as

 

double

 

int

 

public

 

try

 

 

 

 

 

 

 

 

 

base

 

else

 

interface

 

readonly

 

typeof

 

 

 

 

 

 

 

 

 

bool

 

enum

 

internal

 

ref

 

uint

 

 

 

 

 

 

 

 

 

break

 

event

 

is

 

return

 

ulong

 

 

 

 

 

 

 

 

 

byte

 

explicit

 

lock

 

sbyte

 

unchecked

 

 

 

 

 

 

 

 

 

case

 

extern

 

long

 

sealed

 

unsafe

 

 

 

 

 

 

 

 

 

catch

 

false

 

namespace

 

short

 

ushort

 

 

 

 

 

 

 

 

 

char

 

finally

 

new

 

sizeof

 

using

 

 

 

 

 

 

 

 

 

checked

 

fixed

 

null

 

stackalloc

 

virtual

 

 

 

 

 

 

 

 

 

class

 

float

 

object

 

static

 

void

 

 

 

 

 

 

 

 

 

const

 

for

 

operator

 

string

 

volatile

 

 

 

 

 

 

 

 

 

continue

 

foreach

 

out

 

struct

 

while

 

 

 

 

 

 

 

 

 

decimal

 

goto

 

override

 

switch

 

 

 

 

 

 

 

 

 

 

 

default

 

if

 

params

 

this

 

 

 

 

 

 

 

 

 

 

 

delegate

 

implicit

 

private

 

throw

 

 

 

 

 

 

 

 

 

 

 

You can find this list of C# keywords by looking up 'keyword, C#' using the online help's Index facility. The online help topic is then hyperlinked to the definition of each keyword.

Variables

A variable combines a type with a way to store a value of the specified type. (I discuss types later in this chapter, but you are certainly already familiar with some of the C# types, such as int [integer] and string.) The value of a variable can be assigned, and that value can also be changed programmatically at any point.

A variable is created in C# by declaring its type and then giving it an identifier. For example:

int theInt; string deeFlat;

The variable can be initialized, meaning given an initial value, at the time it is declaredalthough this is not required. Here are the same variables declared and initialized:

int theInt = 42;

string deeFlat = "This is a string!";

Alternatively, of course, with the same effect, you could declare the variables and later assign them values:

int theInt; string deeFlat;

...

theInt = 42;

deeFlat = "This is a string!";

To digress for a second here: you may not know that even simple value types such as int inherit from object. This implies that you could declare an int (or other value type) variable using the new constructor. So

int i = new int();

is the equivalent to the standard int declaration:

int i;

Definite Assignment

One thing you should know is that C# requires that variables be assigned a value-either through initialization or programmatic assignment-before they are used. This is known as definite assignment and codifies what is good practice in any case. As they say, an uninitialized variable is like an unmade bed-you never know what you'll find in it.

For example,

string unMadeBed;

MessageBox.Show(unMadeBed, "Hello, Variables!", MessageBoxButtons.OK);

produces a syntax error and will not compile because of the attempted use of an unassigned variable.

Constants

A constant is an identifier used in place of a value. (You can think of a constant as a variable whose value cannot be changed.) Constants should be used for fixed values that occur many places in your code. They should also be used in place of a value whose purpose is not immediately clear from the value.

Constants used in this way-also called symbolic constants-are declared in C# using the const keyword followed by the constant's type, an identifier, and the assignment of value. A constant must be initialized when it is declared, and once it has been initialized the value cannot be changed.

For example, here are the declarations for three notional constants:

const int maxSearchRecords = 41928; const decimal interestRate = 6.75M;

const string companyMotto = "Best of the Best of the Best!";

The first of these, maxSearchRecords, might represent the maximum number of records in a search routine. Even if you use this value only once, using an identifier in this manner makes it much clearer what it represents than would be the case if the value itself was used.

Note For constants that you may need to change, it is also a good idea to put them in a place where you can find them-at the top of a procedure, or in their own class module, as appropriate.

The second constant, interestRate, might be used in a financial application. The M following the value tells the compiler that the value is of type decimal rather than double. Assigning 6.75, which alone would be a literal of type double, to a decimal-type constant would produce a conversion error. (The trailing letter here can be upperor lowercase: m or M.)

If the interestRate value is used repeatedly in the program, it's certainly easier-and a better practice-to only change it once, when the constant value is assigned, rather than throughout the application. (Of course, in the real world you'd probably want to do this technique one better and provide a way to change the interest rate used without having to edit-and recompilecode.)

The final constant example, companyMotto, is included primarily to show that constants can contain string values, as well as other data types. Here's companyMotto used with a MessageBox.Show method:

MessageBox.Show(companyMotto, "Sir!", MessageBoxButtons.OK);

The same reasons for using constants rather than literal values apply to string types, and perhaps companyMotto is an example of this: You don't have to retype the string in numerous places in your application, and if the company changes its motto, you only have to change it in one place.

Note Dynamic properties, found at the top of the Properties window, allow you to load properties from an external configuration file. These values, which can easily be changed without the need for recompiling a project, can be used in the place of constants in an application. For more information, look up 'Introduction to Dynamic Properties' in online help.

Enumeration Constants

Enumerations are lists of named constants-called enumeration constants-of the same type. (The list of constants within an enumeration is also called the enumerator list.)

Built-In Enumerations

You've almost certainly used the enumeration constants that are part of the .NET Framework's pre-built types. For example, use of the MessageBox.Show method was explained in Chapter 3, "Windows Uses Web Services, Too!".

The fourth MessageBox.Show method argument represents the icon that will be displayed in the message box. This icon is selected by choosing from a list of enumeration constants, each a member of the MessageBoxIcon enumeration. You'll see the list of constants for the enumeration supplied by the auto-completion feature of the Code Editor when you type in a MessageBox.Show (Figure 6.1).

Figure 6.1: The auto-completion feature of the Code Editor supplies the members of an enumerator list.

You can also find member information for an enumerator list in the Object Browser, as shown in Figure 6.2.

Figure 6.2: The members of an enumeration constant list are shown in the Object Browser.

The icon that represents the choice made by the selection of the enumeration constant from the list of MessageBoxIcon members will be displayed when the message box is displayed:

const string companyMotto = "Best of the Best of the Best!"; MessageBox.Show(companyMotto, "Sir!", MessageBoxButtons.OK,

MessageBoxIcon.Exclamation);

Custom Enumerations

Enumerations are too good to just use with types provided by .NET-you'll want to use your own enumerations, using the enum keyword, in situations where related items form a natural list of possibilities.

An enumeration has a base type, which is the underlying C# intrinsic type for items in the enumeration. If the base type of an enumeration is not specified, it defaults to int. In addition, you needn't assign a value to each enumeration constant (but you can if you wish). In the default case, the first item in the enumerator list has a value of zero, and each successive enumerator is increased by one. For example, if you created an enumeration named toys with three items:

enum toys {train, dinosaur, truck};

the items would have values as follows:

 

 

 

Enumerator

 

Value

 

 

toys.train

 

0

 

 

toys.dinosaur

 

1

 

 

toys.truck

 

2

 

 

 

Now, when you attempt to use this enumeration, the members appear alphabetically in the Code Editor's auto-completion list, just like a built-in enumeration.

The members of the toys enumeration will also appear in the Object Browser.