1
Introduction to C# Introduction Overview of C# C#, pronounced c sharp, is a computer language used to give instructions that tell the computer what to do, how to do it, and when to do it. This is a universal language that, although currently mostly used on the Microsoft Windows operating system, will be also used on other operating systems like Linux, BeOS, Macintosh, etc. C# is one of the languages used in the Microsoft .NET Framework. The Microsoft .NET Framework is a library of objects that create or draw things on the computer. The C# language is used to create applications that display on a black window referred to as the DOS prompt or DOS window.
Introduction to Objects An object, any object, is made of different parts. For example, a car is made of tires, doors, wires, belts, etc:
In computer languages, such an object is called a class. In the C# language, everything is built as a class. Therefore, a program starts with the class keyword followed by a name. Here is an example: class Car The actual building of a class starts with an opening curly bracket "{" and ends with a closing curly bracket "}". Therefore, a class can be created as follows:
class Car { }
2
Because a class can be made of numerous parts, such as tires, doors, seats, etc, listed as subobjects of a class, one line could become (too) crowded. Therefore, each curly bracket should be displayed on its own line: class Car { } The assignments of a program written in C# are carried in entities called methods. A method is simply a section of code that takes care of a particular detail for the functionality of the program. To create a method, you must specify its name, which starts with a letter or an underscore and can be followed by letters, digits, or underscores. The name of a method is followed by an opening and a closing parentheses. Here is an example: class Car { Drive() } A method's job is to carry a specific assignment within a program. As such, it could provide a value once the assignment has been carried. In Lesson 8, we will review the types of values that a method can provide. If on the other hand a method doesn't give back a value, then it is considered void. The type of value that a method can provide (or return) is written on the left side of the method name. An example would be: class Car { void Drive() } The assignment that a method carries is included between an opening curly bracket "{" and a closing curly bracket "}". Therefore, a method can be written as follows: class Car { void Drive() { } } Indentation is a technique of specifying where a line of code starts and where it ends. Although indentation is not part of the C# language, it makes the program easier to read. Therefore, the above lines of code can be written as follows: class Car { void Drive() { } } Note that this time, it is easier to know where the class starts and ends, and where the method starts and ends. In some occasions (we will see when and why), we will need to write a method as "static". The most regularly used method of a C# program is called Main. Therefore, the minimum you
3
can write a program with, is as follows: class Car { static void Main() { } } A computer program is started in a regular computer file. A file for a C# program has the extension .cs. To make your programming fast, the C# language ships with many primary files that allow you to lay a foundation for your program.
Command Line Fundamentals Introduction When the computer starts, there is no primary visual or graphical effect. The programs must first be loaded into memory. In fact, in the beginning, the Microsoft operating system started as textbased with DOS 2.2, 3.3, 5.0, and 6.2 (6.2 was never a big hit like 5.0 because Windows 3.1, Windows 3.2, and Windows 3.3 was released at the same time, bringing the now attractive "Windows" display). To create a program, a programmer entered the source code using a text editor (there was a text editor called EDIT; it was very cute, very basic, and very wonderful; in fact, up to Windows 3.3, it was still the text editor of choice of most programmers and it was used as the editor for QBasic, the parent of Visual Basic). After creating the source file, the programmer had to use a black (or "amber") screen that displayed a blinking caret whose role was to let the user know that it was waiting for a command. A command was a word or a group of words that the programmer typed and pressed Enter (or Return). This caused the computer to produce an action. The command was typed on a line. For this reason, the area that displayed the caret was called the Command Line. Most low-level (lowlevel doesn't mean weak, to the contrary) programs are still using this concept. This means that, behind the scenes, computer languages such as C/C++, Pascal, Java, C#, etc, are still created and executed as if things were done at the Command Line.
Command Line Understanding To be an effective programmer, it is important to know how the Command Line works because, as mentioned already, C# programs are compiled at the Command Prompt. If you know how the Command Line works, you can have a better understanding of things that are going on behind the scenes. As its name indicates, the Command Line is a blank line with a blinking caret that expects you to type a command:
4
There are various types of commands used on the command prompt. Some of them are as old as the operating system. Such is the case for commands used to create files or folders, copy files or folders, delete files or folders, format a drive, etc. Some other commands are created by a person like you who needs it for a particular application. For example, the C# language provides a command called csc to compile a program at the command line. In the same way, when you create a program, particularly when you create a source file, you can use some options that would be used at the command prompt.
The Compiler You may have realized that all of the words we have used so far, such as class, void, or static, are regular English words that you can read and whose meaning you can find in a dictionary. Computer languages are created with meaningful words like that to make them easier to read and understand. Unfortunately, the computer doesn't understand those words and cannot execute the instructions those words represent. Like most other languages, C# is just a language that is used to give instructions to the computer. To make the computer understand these instructions, you need another, somehow more powerful, program. This program would receive the language's instructions in plain English and "translate" them in another language that the computer can understand. This program is called a compiler. A compiler is a computer program made of internal other sub-programs. One of the subprograms, in fact probably the first, of a compiler is called a parser. A parser "scans" a file that contains (part of) the program. It checks for syntax, keywords, unknown words, and some other routines. If the parser finds a problem, which could be anything, either it stops or it continues making a list of the mistakes it found. Then it displays this list to you to fix. Sometimes it would point to the exact line where the/a problem was found. Sometimes it would point to the line where the problem showed its impact although the problem may be found somewhere else. With experience, you will know how to fix the programs or troubleshoot these problems. On this site, we will address as many issues as possible. If the parser doesn't find any problem, or after you have fixed the problems, it (the parser) passes its result(s) to the compiler. The compiler calls another program called a linker. If the program contains just one file, the linker considers it. If the program contains more than one file (because a program can contain as many files as necessary), the linker considers them. The linker gathers some of the files that the C# compiler shipped with (those files that your program needs in order to work, since your program doesn't need all possible files that C# ships with), puts them together ("links" them) with your file(s) to get your instructions in a manner that can produce a suitable result. If there is no significant problem, the compiler creates the program. This doesn't mean that everything is alright, it only means that the compiler thinks that everything is alright: it is still possible that the result may not be what you would expect. To make your life easier, all of the sub-programs (parser, linker, debugger, etc) that ship with C# are grouped in one large program: the compiler. Therefore, from now on, we will use the word
5
"compiler" to refer to the program you use to "translate" your English-based instructions into a computer-based language. The compiler that ships with the C# version we will use, that is, the compiler of the .NET Framework is a program called csc. Like most other programs, it has the extension .exe. This csc name is not standard. This means that another C# compiler may have another name; csc.exe is just the name of the compiler we will use.
Creating a Program On this site, we will use Microsoft Visual Studio .NET to create our programs. To use it, you have two main options. You can start from an empty project and add the necessary files, or you can create a console application using its Option.
Practical Learning: Creating a Program 1. Start Microsoft Visual C# or Visual Studio .NET 2. On the main menu, click File -> New -> Project 3. If necessary, in the Project Types list of the New Project dialog box, click Visual C# Projects 4. In the Templates list, click Empty Project
5. In the Name text box, replace the name with Exercise1 and specify the desired path in the Location
6. Click OK 7. To create a source file for the project, on the main menu, click Project -> Add New Item...
6 8. In the Add New Item dialog box, in the Templates list, click Code File
9. In the Name text box, delete the suggested name and replace it with Exercise
10. Click Open 11. In the empty file, type the following: class OrderProcessing { static void Main() { } } 12. To save the file, on the main menu, click File -> Save
7 13. To execute the application, on the main menu, click Debug -> Start Without Debugging
14. Press Enter to close the DOS window and return to Visual C#
Namespaces Introduction When many people work in creating the same program, it could be difficult to keep track of the names of various classes. If more than one programmer creates a class with the same name in the same program, there would be conflict and the program would not work. The solution to avoid this situation is to delimit sections of code with names. A namespace is a section of code that is identified by a specific name. The name could be anything such as somebody's name, the name of the company's department, or a city. To create a namespace, you start with the namespace keyword followed by the name of the section. Like a class, the section that is part of a namespace starts with an opening curly bracket "{" and ends with a closing curly bracket "}". Here is an example: namespace Jason { } Between the curly brackets, you can type anything that is part of the namespace. For example, you can create a class inside of a namespace. Here is an example:
8 namespace Jason { class Airport { } }
Practical Learning: Creating a Namespace 1. To create a namespace, change the file as follows: namespace GeorgetownCleaners { class OrderProcessing { static void Main() { } } } 2. Save the file
Accessing Members of a Namespace After creating the necessary items in a namespace, you can use the period operator to access an item that is part of the namespace. To do this, in the desired location, type the name of the namespace, followed by a period, followed by the desired member of the namespace. Here is an example: namespace Accounting { class Departure { } } class MainClass { static void Main() { Accounting.Departure } }
Namespace Nesting Imagine that you create a namespace called Accounting and many people from the Accounting department are asked to create their methods and objects only in the Accounting namespace and you may have asked the Accounting programmers not to create their methods and objects outside of the Accounting namespace. One thing you can do is to create other namespaces inside of the existing namespace. Creating a namespace inside of an existing namespace is referred to as nesting the namespace. The namespace inside of another namespace is nested. To create a namespace inside of another, simply type it as you would create another namespace. Here is an
9
example: namespace Accounting { namespace Jason { } } In the example above, the Jason namespace is nested inside of the Accounting namespace. After creating the needed namespaces, nested or not, you can create the necessary methods and objects inside of the desired namespace. To access anything that is included in a nested namespace, you use the period operator before calling a member of a namespace or before calling the next nested namespace. Here is an example: namespace Accounting { class Payroll { } } namespace Personnel { namespace EmployeesRecords { class TimeSheet { } } namespace Benefits { class MedicalInsurance { } } } class MainClass { static void Main() { Accounting.Payroll Personnel.Benefits.MedicalInsurance Personnel.EmployeesRecords.TimeSheet } } A line of code such as Accounting.Payroll is called a statement. Every statement must be terminated with a colon. Therefore, this statement may be written as: Accounting.Payroll;
The System Namespace
10
Introduction To make programming in C# a little easier, many classes have already been created and stored in various namespaces. Each namespace in C# is used to provide a specify set of classes. The most regularly used namespace in the C# language is called System. Inside of the System namespace is a class called Console. The Console class is used to display things on the console screen also called the DOS window. The Console class contains assignments (called methods) to display information on the screen or to retrieve information from the user who types it in the DOS window. The method that is used to display text on the screen is called Write. To use the Write() method, inside of the parentheses, type the sentence between double-quotes. Here is an example: class Program { static void Main() { System.Console.Write("The Wonderful World of C# Programming"); } } Besides the Write() method, the Console class also provides a method called WriteLine(). The difference is that, after displaying something on the screen, the Write() method keeps the caret on the same line but WriteLine() transfers the caret the next line. We will see various examples of this behavior throughout our lessons.
Practical Learning: Introducing Console Methods 1. To use the System namespace, change the contents of the file as follows: namespace GeorgetownCleaners { class OrderProcessing { static void Main() { System.Console.WriteLine("Georgetown Cleaning Services"); } } }
2. Execute the application again to see the result
11
3. Press Enter to close the window and return to Visual C#
The Using Keyword We saw that, to call an object or a method that is part of a namespace, you must "qualify" that method or object using the period operator. Instead of using this approach, if you already know the name of a namespace that exists or has been created in another file, you can use a special keyword to indicate that you are using a namespace that is defined somewhere. This is done with the using keyword. To do this, on top of the file (preferably), type using followed by the name of the namespace. With the using keyword, you can include as many external namespaces as necessary.
Practical Learning: Using the Keyword 1. Change the file as follows: using System; namespace GeorgetownCleaners { class OrderProcessing { static void Main() { Console.WriteLine("Georgetown Cleaning Services"); } } }
12
2. Execute the application to test it 3. Return to Visual C# 4. To create an application using a wizard, on the main menu, click File -> New -> Project 5. In the Project Types list of the New Project dialog box, make sure Visual C# Projects is selected. In the Templates list, click Console Application
6. In the Name text box, replace the name with Exercise2 and specify the desired path in the Location
7. Click OK 8. To change the name of the file, in Solution Explorer, right-click Class1 and click Rename
9. Type Exercise.cs and press Enter 10. To rename the class, in the Code Editor, double-click Class1 and type OrderProcessing 11. Execute the application
Accessories for Coding Comments A comment is a line or paragraph of text that the compiler would not consider when examining the code of a program. There are two types of comments recognized by C#. To display a comment on a line of text, start the line with two forward slashes //. Anything on the right side of // would be ignored. Here is an example:
13
// This line will be ignored. I can write in it anything I want The above type of comment is used on only one line. You can also start a comment with /*. This type of comment ends with */. Anything between this combination of /* and */ would not be read by the compiler. Therefore, you can use this technique to span a comment on more than one line.
Practical Learning: Creating Comments 1. To create comments, change the file as follows: // Project Name: Exercise // Purpose: Used to process cleaning orders for customers using System; // Orders and business-related operations will be performed here namespace GeorgetownCleaners { class OrderProcessing { static void Main() { Console.WriteLine("Georgetown Cleaning Services"); } } } 2. Execute the application to test it 3. Close the window and return to Visual C#
Command Line Options To see the name of the executable created for the above project, you can open Windows Explorer or My Computer, display the contents of the Exercise1 folder, followed by bin, and followed by debug. You would find a program called exercise1.exe
14
By default, Microsoft Visual C# uses the name of the project to create the name of the executable of a project. In some cases, you may want to use a different name. To specify this information, you can open the properties of the project. To do this, you can click Project -> ProjectName Properties... from the main menu. Alternatively, in the Solution Explorer, you can right-click the name of the project and click Properties. Once in the properties, change the name of the Assembly Name.
Practical Learning: Specifying the Name of the Executable 1. Click anywhere in the source file to make sure the project is selected. On the main menu, click Project -> Exercise1 Properties...
2. To specify a custom name, delete the contents of Assembly Name and type Georgetown Cleaning Services
15
3. Click OK 4. Execute the application 5. Open Windows Explorer or My Computer and display the contents of the Exercise1\bin\debug folder to notice an executable named Georgetown Cleaning Services 6. Return to Visual C#
Unsafe Code When C# was invented, one of its biggest goals was to avoid some of the difficulties of C/C++. Among them was the use of pointers for people who couldn't stand them or those who don't like or can't stand their intricacies. C/C++ uses pointers to refer to the area in memory where a value is located. C# highly avoids pointers and takes over memory management as opposed to letting the programmer take care of that aspect of an application. You can still use pointers in C# in extreme cases you judge them necessary. Because the C# compiler is in charge of managing the memory used by the values of an application, pointers are said to be unsafe. If you want to use a pointer in your application, you must precede the name of every method that uses unsafe code with the unsafe keyword. To compile the application, you must indicate that you are using unsafe code. To do that, use the /unsafe modifier.
16
Variables Overview Definition A computer receives information from different applications in various forms. Sometimes a person types it using the keyboard. Sometimes the user clicks the mouse. Sometimes information comes from another, more complicated source. The idea is that the computer spends a great deal of its time with various pieces of information. Information provided to the computer through a program is called datum and the plural is data. Sometimes the word data is used both for singular and plural items. Data used by the computer comes and goes regularly as this information changes. For this reason, such information is called a variable. When the user enters data in a program, the computer receives it and must store it somewhere to eventually make it available to the program as needed. For a program used to process employment applications, the types of information a user would enter into the program are the name, the residence, the desired salary, years of experience, education level, etc. Because there can be so much information for the same program, you must specify to the computer what information you are referring to and when. To do this, each category of piece of information must have a name.
Names in C# To name the variables of your program, you must follow strict rules. In fact, everything else in your program must have a name. C# uses a series of words, called keywords, for its internal use. This means that you must avoid naming your objects using one of these keywords. They are: abstract
const
extern
int
out
short
typeof
as
continue
false
interface
override
sizeof
uint
base
decimal
finally
internal
params
stackalloc
ulong
bool
default
fixed
is
private
static
unchecked
break
delegate
float
lock
protected string
unsafe
byte
do
for
long
public
struct
ushort
case
double
foreach
namespace readonly
switch
using
catch
else
goto
new
ref
this
virtual
char
enum
if
null
return
throw
void
checked
event
implicit
object
sbyte
true
volatile
class
explicit
in
operator
sealed
try
while
Once you avoid these words, there are rules you must follow when naming your objects. On this
17
site, here are the rules we will follow: •
The name must start with a letter or an underscore
•
After the first letter or underscore, the name can have letters, digits, and/or underscores
•
The name must not have any special characters other than the underscore
•
The name cannot have a space
Besides these rules, you can also create your own but that abide by the above. C# is case-sensitive. This means that the names Case, case, and CASE are completely different. For example, the main function is always written Main.
The Numeric Systems Introduction When a computer boots, it “loads” the operating system. If you want to use a program, you must find it either on the Start menu or from its directory and take the necessary action to open it. Such a program uses numbers, characters, meaningful words, pictures, graphics, etc, that are part of the program. As these things are numerous, so is the size of the program, and so is the length of time needed to come up. Your job as a programmer is to create such programs and make them available to the computer, then to people who want to interact with the machine. To write your programs, you will be using alphabetic letters that are a, b, c, d, e, f, g, h, I, j, k, l, m, n, o, p, q, r, s, t, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z. You will also use numeric symbols 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Additionally, you will use characters that are not easily readable but are part of the common language; they are ` ~ ! @ # $ % ^ & * ( ) _ + - = : “ < > ; ‘ , . /. Some of these symbols are used in the C# language while some others are not. When creating your programs, you will be combining letters and/or symbols to create English words or language instructions. Some of the instructions you will give to the computer could consist of counting the number of oranges, converting water to soup, or making sure that a date occurs after January 15. After typing an instruction, the compiler would translate it to machine language. The computer represents any of your instructions as a group of numbers. Even if you ask the computer to use an orange, it would translate it into a set of numbers. As you give more instructions or create more words, the computer stores them in its memory using a certain amount of space for each instruction or each item you use. There are three numeric systems that will be involved in your programs, with or without your intervention.
The Binary System When dealing with assignments, the computer considers a piece of information to be true or to be false. To evaluate such a piece, it uses two symbols: 0 and 1. When a piece of information is true, the computer gives it a value of 1; otherwise, its value is 0. Therefore, the system that the computer recognizes and uses is made of two symbols: 0 and 1. As the information in your computer is greater than a simple piece, the computer combines 0s and 1s to produce all sorts of
18
numbers. Examples of such numbers are 1, 100, 1011, or 1101111011. Therefore, because this technique uses only two symbols, it is called the binary system. When reading a binary number such as 1101, you should not pronounce "One Thousand One Hundred And 1", because such a reading is not accurate. Instead, you should pronounce 1 as One and 0 as zero or o. 1101 should be pronounced One One Zero One, or One One o One. The sequence of the symbols of the binary system depends on the number that needs to be represented.
The Decimal System The numeric system that we are familiar with uses ten symbols that are 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9. Each of these symbols is called a digit. Using a combination of these digits, you can display numeric values of any kind, such as 240, 3826 or 234523. This system of representing numeric values is called the decimal system because it is based on 10 digits. When a number starts with 0, a calculator or a computer ignores the 0. Consequently, 0248 is the same as 248; 030426 is the same as 30426. From now on, we will represent a numeric value in the decimal system without starting with 0: this will reduce, if not eliminate, any confusion. Decimal Values: 3849, Non- Decimal Values: 0237, 0276382, k2783, R3273
279,
917293,
39473
The decimal system is said to use a base 10. This allows you to recognize and be able to read any number. The system works in increments of 0, 10, 100, 1000, 10000, and up. In the decimal system, 0 is 0*100 (= 0*1, which is 0); 1 is 1*100 (=1*1, which is 1); 2 is 2*100 (=2*1, which is 2), and 9 is 9*100 (= 9*1, which is 9). Between 10 and 99, a number is represented by left-digit * 101 + right-digit * 100. For example, 32 = 3*101 + 2*100 = 3*10 + 2*1 = 30 + 2 = 32. In the same way, 85 = 8*101 + 5*100 = 8*10 + 5*1 = 80 + 5 = 85. Using the same logic, you can get any number in the decimal system. Examples are: 2751 = 2*103 + 7*102 + 5*101 + 1*100 = 2*1000 + 7*100 + 5*10 + 1 = 2000 + 700 + 50 + 1 = 2751 67048 = 6*104 + 7*103 + 0*102 + 4*101 + 8*100 = 6*10000 + 7*1000+0*100+4*10+8*1 = 67048 Another way you can represent this is by using the following table: etc
Add 0 to the preceding value
1000000 100000 10000 1000 100 10
0
When these numbers get large, they become difficult to read; an example is 279174394327. To make this easier to read, you can separate each thousand fraction with a comma. Our number would become 279,174,394,327. You can do this only on paper, never in a program: the compiler would not understand the comma(s).
The Hexadecimal System
19
While the decimal system uses 10 digits (they are all numeric), the hexadecimal system uses sixteen (16) symbols to represent a number. Since the family of Latin languages consists of only 10 digits, we cannot make up new ones. To compensate for this, the hexadecimal system uses alphabetic characters. After counting from 0 to 9, the system uses letters until it gets 16 different values. The letters used are a, b, c, d, e, and f, or their uppercase equivalents A, B, C, D, E, and F. The hexadecimal system counts as follows: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, and f; or 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. To produce a hexadecimal number, you use a combination of these sixteen symbols. Examples of hexadecimal numbers are 293, 0, df, a37, c23b34, or ffed54. At first glance, the decimal representation of 8024 and the hexadecimal representation of 8024 are the same. Also, when you see fed, is it a name of a federal agency or a hexadecimal number? Does CAB represent a taxi, a social organization, or a hexadecimal number? From now on, to express the difference between a decimal number and a hexadecimal one, each hexadecimal number will start with 0x or 0X. The number will be followed by a valid hexadecimal combination. The letter can be in uppercase or lowercase. Legal Hexadecimals: 0x273, 0xfeaa, 0Xfe3, 0x35FD, 0x32F4e Non-Hex Numbers: 0686, ffekj, 87fe6y, 312 There is also the octal system but we will not use it anywhere in our applications.
Signed and unsigned The numbers we have used so far were counting from 0, then 1, then 2, and up to any number desired, in incrementing values. Such a number that increments from 0, 1, 2, and up is qualified as positive. By convention, you do not need to let the computer or someone else know that such a number is positive: by just displaying or saying it, the number is considered positive. This is the basis of our counting items. In real life, there are numbers counted in decrement values. Such numbers start at –1 and move down to -2, -3, -4 etc. These numbers are qualified as negative. When you write a number “normally”, such as 42, 502, or 1250, the number is positive. If you want to express the number as negative, you use the – on the left side of the number. The – symbol is called a sign. Therefore, if the number does not have the – symbol, C++ (or the compiler) considers such a number as unsigned. In C++, if you declare a variable that would represent a numeric value and you do not initialize (assign a value to) such a variable, the compiler will consider that the variable can hold either a signed or an unsigned value. If you want to let the compiler know that the variable should hold only a positive value, you will declare such a variable as unsigned.
Data Types In order to use a variable in your program, the compiler must be aware of it. Once the compiler
20
knows about a variable, it would reserve an amount of memory space for that variable
Using its name, you can refer to a particular variable when necessary. Because there are various types of variables a program can use, such as the employee's name, the residence, the desired salary, years of experience, education level, etc for our employment application analogy, the compiler needs a second piece of information for each variable you intend to use. This piece of information specifies the amount of space that a variable needs. You can see that, to store a character, such as an employee's gender (M or F) or an answer as Y or N to a question, the compiler would certainly not need the same amount of space to store the name of the last school attended by an employee. A data type is an amount of space needed to store the information related to a particular variable. The name of a variable allows you and the compiler to refer to a particular category of information in your program. The data type allows the compiler to reserve an adequate amount of memory space for a variable. Because you are the one who writes a program, you also tell the compiler the amount of memory space each particular variable will need. Based on this, the C# language provides categories of data types used to specify this amount of space needed for a variable.,/p> As stated already, before using a variable, you must communicate your intentions to the compiler. Making the compiler aware is referred to as declaring the variable. To declare a variable, provide the data type followed by the name of the variable. Therefore, the syntax used to declare a variable is: DataType VariableName; In the next lesson, we will review the assignment operator. For now, we will know that we can use it to provide a new value to a variable. The assignment operator is represented by =
Practical Learning: Using Variables 1. Start Microsoft Visual C# or Visual Studio .NET 2. On the main menu, click File -> New -> Project 3. If necessary, in the Project Types list of the New Project dialog box, click Visual C# Projects 4. In the Templates list, click Empty Project
5. In the Name text box, replace the name with GCS1 and specify the desired path in the Location
6. Click OK 7. To create a source file for the project, on the main menu, click Project -> Add New Item... 8. In the Add New Item dialog box, in the Templates list, click Code File
9. In the Name text box, delete the suggested name and replace it with Exercise 10. Click Open
21 11. In the empty file, type the following: using System; namespace GeorgetownCleaners { class OrderProcessing { static void Main() { Console.WriteLine("-/- Georgetown Cleaning Services -/-"); } } } 12. To execute the application, on the main menu, click Debug -> Start Without Debugging 13. Press Enter to close the DOS window and return to Visual C#
Representing Numbers A Bit The computer (or an Intel computer, or a computer that runs on an Intel microprocessor) uses the binary system to represent its information. It represents data using only a 0 or 1 value. To make an illustration, let's consider that a computer uses a (small) cup (such as a cup of coffee) to represent such a value. This cup can have only one of two states. When the cup is empty, we will give it a value of 0. When the cup is full, we give it a value of 1. The box can have only one of these two values:
0
1
Since this cup can have only one of two states, consider that you can use it to represent anything that could assume one out of two states. Examples include: True-False; Parent-Child; On-Off; Discount-NoDiscount; Male-Female; Yes-No, etc. This technique of representing values is the same as the binary system we mentioned earlier. In the computer, it uses values 0 and/or 1, which themselves are called digits. The entity used to represent such a value is called a binary digit; in its abbreviated form, it is called a bit (for binary digit). The bit (binary digit) is the most fundamental representation of the computer's counting system. Although the C# compiler recognizes a bit, you cannot store a variable in a bit. However, eventually, you will be able to manipulate the information stored in a bit.
The Four-Bit Combination The single bit is used only to represent a tinny piece of information. To get effective numbers, the computer combines the bits. The first combination of bits consists of grouping four
22
consecutive bits.
To count the bits, we number them starting at 0, followed by 1, 2, and 3. The count starts with the most right bit.
The first bit, on the right side of the group, is called the Low Order bit or LO bit. This is also called the least significant bit. The last bit, on the left side of the group, is called the High Order bit or HI bit; it is also called the most significant bit. The bit on the right side is counted as bit 0. The bit on the left side is counted as bit 3. The other bits are called by their positions: bit 1 and bit 2. Once again, each bit can have one of two states. Continuing with our illustration, when a cup is empty, it receives a value of 0. Otherwise, it has a value of 1. On a group of four consecutive bits, we can have the following combinations:
This produces the following binary combinations: 0000, 0001, 0010, 0011, 0100, 0101, 0110, 0111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111 = 16 combinations. When using the decimal system, these combinations can be represented as 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, and 15. This combination is also a system that the computer uses to count bits internally. Sometimes, in your program or in the help files, you will encounter a number that is less than four bits, such as 10 or 01 or 101. The technique used to complete and fill out the group of 4 bits consists of displaying 0 for each non-represented bit. The binary number 10 will be the same as 0010. The number 01 is the same as 0001. The number 101 is the same as 0101. This technique is valuable and allows you to always identify a binary number as a divider of 4. When all bits of a group of 4 are 0, the combination has the lowest value, which is 0000. Any of the other combinations has at least one 0 bit, except for the last one. When all bits are 1, this provides the highest value possible for a group of 4 bits. The lowest value, also considered the minimum value, can be represented in the decimal system as 0. The highest value, also considered the maximum, can be expressed in decimal value as 24 (2 represents the fact that
23
there are two possible states: 0 and 1; 4 represents the fact that there are four possible combinations), which is 16. This produces 16 because 24 = 16. As you can see, the binary system can appear difficult to read when a value combines various bit representations. To make it easier, the computer recognizes the hexadecimal representation of bits. Following the box combinations above, we can represent each 4-bit of the sixteen combinations using the decimal, hexadecimal, and binary systems as follows: Decimal 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Binary 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
Hexadecimal 0 1 2 3 4 5 6 7 8 9 A B C D E F
Table of Numeric Conversions When looking at a binary value represented by 4 bits, you can get its decimal or hexadecimal values by referring to the table above. A group of four consecutive bits has a minimum and maximum values on each system as follows:
Minimum Maximum
Decimal 0 15
Hexadecimal 0x0 0xf
Binary 0000 1111
Although the C# compiler recognizes a group of four consecutive bits, you cannot store any variable in it. You can, however, manipulate the bits of the group.
A Byte Introduction
24
A byte is a group or eight consecutive bits. The bits are counted from right to left starting at 0. The most right bit is bit 0; it is called the least significant bit. It is also referred to as the Low Order bit, the LO bit, or LOBIT. The most left bit is bit 7; it is called the most significant bit. It is also referred to as the High Order bit, the HI bit, or HIBIT. The other bits are referred to following their positions.
Using the binary system, you can represent the byte using a combination of 0s and 1s. When all bits have a value of 0, the byte is represented as 00000000. On the other hand, when all bits have a value of 1, the byte is represented as 11111111. When the number grows very large, it becomes difficult to read. Therefore, you can represent bits in groups of four. Instead of writing 00000000, you can write 0000 0000. This makes the number easier to read. If you have the patience to create combinations of bits using the cups as we did for the group of 4, you would find out that there are 256 possible combinations. Another way to find it out is by using the base 2 technique: 27 + = 128 = 255
26 +
+ 64
25 +
+ 32
24 +
+ 16
23 +
+ 8
+
22
4
+
+
21
2
+ +
20 1
Therefore, the maximum decimal value you can store in a byte is 255. Remember that the byte with all bits having a value of 0 has its value set to 0. Since this byte also holds a valid value, the number of combinations = 255 + 1 = 256.
When a byte is completely represented with 0s, it provides the minimum value it can hold; this is 0000 0000, which is also 0. When all bits have a value of 1, which is 1111 1111, a byte holds its maximum value that we calculated as 255 in the decimal system. As done with the group of 4 bits, we get the following table:
25
Minimum Maximum
Decimal 0 255
Hexadecimal 0x0 0xff
Binary 0000 1111 1111
The minimum storage area offered by the (Intel) computer is the byte. As you know already, a byte is a group of 8 consecutive bits. The amount of memory space offered by a byte can be used to store just a single symbol, such as those you see on your keyboard. These symbols, also called characters, have been organized by the American Standard Code for Information Exchange (ASCII) in a set list. But, ASCII uses only 128 decimal numbers (based on a 7-bit format) to represent symbols counted from 0 to 127. To compensate for the remaining 1 bit, IBM used it to organize special characters, foreign language characters, mathematical symbols, small graphics, etc. Each one of these characters has a decimal, a hexadecimal, and a binary equivalents. Each one of the characters you see on your keyboard is represented as a numeric value, but whether it appears as a number, a letter, or a symbol, each one of these is considered a character. To display any character on your screen, you can pass it to Write() or WriteLine() and include the character between single-quotes, as follows: using System; class Exercise { static void Main() { Console.WriteLine('n'); } }
Characters
In the English alphabet, a character is one of the following symbols: a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, and Z. Besides these readable characters, the following symbols are called digits and they are used to represent numbers: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. In addition, some symbols on the (US QWERTY) keyboard are also called characters or symbols. They are ` ~ ! @ # $ % ^ & * ()-_=+[{]}\|;:'./,>" Besides the English language, other languages use other or additional characters that represent verbal or written expressions. C# recognizes that everything that can be displayed as a symbol is called a character. To declare a variable whose value would be a character, use the char keyword. Here is an example: using System; class ObjectName { static void Main() { char Gender = 'M';
} }
Console.Write("Student Gender: "); Console.WriteLine(Gender);
26
This would produce: Student Gender: M
The Byte Data Type A byte is an unsigned number whose value can range from 0 to 255 and therefore can be store in one byte. You can use it when you know a variable would hold a relatively small value such as people's age, the number of children of one mother, etc. To declare a variable that would hold a small natural number, use the byte keyword. Here is an example: byte Age; You can initialize a byte variable when declaring it or afterwards. Here is an example that uses the byte data type: using System; class ObjectName { static void Main() { Byte Age = 14; Console.Write("Student Age: "); Console.WriteLine(Age); Age = 12; Console.Write("Student Age: "); Console.WriteLine(Age); }
} Make sure you do not use a value that is higher than 255 for a byte variable, you would receive an error. When in doubt, or when you think that there is a possibility a variable would hold a bigger value, don't use the byte data type as it doesn't like exceeding the 255 value limit.
Practical Learning: Using Bytes 1. To use byte variables, change the file as follows: using System; namespace GeorgetownCleaners { class OrderProcessing { static void Main() { byte NumberOfShirts; byte NumberOfPants; NumberOfShirts = 4; NumberOfPants = 1; Console.WriteLine("-/- Georgetown Cleaning
27 Services -/-");
}
Console.WriteLine("========================"); Console.WriteLine("Item Type Qty"); Console.WriteLine("------------------------"); Console.Write("Shirts "); Console.WriteLine(NumberOfShirts); Console.Write("Pants "); Console.WriteLine(NumberOfPants); Console.WriteLine("========================"); Console.WriteLine();
}
}
2. Execute the program. This would produce: -/- Georgetown Cleaning Services -/======================== Item Type Qty -----------------------Shirts 4 Pants 1 ======================== 3. Return to Visual C#
Signed Byte A byte number is referred to as signed if it can hold a negative or a positive value that ranges from -128 to 127, which can therefore fit in a byte. To declare a variable for that kind of value, use the sbyte keyword. Here is an example: using System; class NumericRepresentation { static void Main() { sbyte RoomTemperature = -88;
}
Console.Write("When we entered, the room temperature was "); Console.WriteLine(RoomTemperature); Console.WriteLine();
} This would produce: When we entered, the room temperature was -88
A Word Introduction
28
A word is a group of 16 consecutive bits. The bits are counted from right to left starting at 0:
Considered as a group of 16 bits, the most right bit of a word, bit 0, is called the least significant bit or Low Order bit or LO bit or LOBIT. The most left bit, bit 15, is called the most significant bit or High Order bit or HI bit or HIBIT. The other bits are referred to using their positions: bit 1, bit 2, bit 3, etc. Considering that a word is made of two bytes, the group of the right 8 bits is called the least significant byte or Low Order byte or LO byte or LOBYTE. The other group is called the most significant byte or High Order byte or HI byte or HIBYTE.
The representation of a word in binary format is 0000000000000000. To make it easier to read, you can group bits by 4, like this: 0000 0000 0000 0000. Therefore, the minimum binary value represented by a word is 0000 0000 0000 0000. The minimum decimal value of a word is 0. The minimum hexadecimal value you can store in a word is 0x0000000000000000. This is also represented as 0x00000000, or 0x0000, or 0x0. All these numbers produce the same value, which is 0x0. The maximum binary value represented by a word is 1111 1111 1111 1111. To find out the maximum decimal value of a word, you can use the base 2 formula, filling out each bit with 1: 1*215+1*214+1*213 + 1*212 + 1*211 + 1*210 + 1*29 + 1*28 + 1*27 + 1*26 + 1*25 + 1*24 + 1*23 + 1*22 + 1*21 + 1*20 = 32768 + 16384 + 8192 + 4096 + 2048 + 1024 + 512 + 256 + 128 + 64 + 32 + 16 + 8 + 4 +2+1 = 65535 To find out the maximum hexadecimal number you can store in a word, replace every group of 4 bits with an f or F: 1111 1111 1111 1111 f f f f = 0xffff = 0xFFFF = 0Xffff
29 = 0XFFFF
Short Integers A word, which is a group of 16 contiguous bits or 2 bytes, can be used to hold a natural number. As we have studied, the maximum numeric value that can fit in a word is 65535. Since the byte is used for very small numbers, whenever you plan to use a number in your program, the minimum representation you should use is a word. The smallest integer you can store in a word is declared with the short keyword followed by a name. Because a short integer is signed by default, it can store a value that ranges from – 32768 to 32767. Here is an example program that uses two short integers: using System; class NumericRepresentation { static void Main() { short NumberOfPages; short Temperature; NumberOfPages = 842; Temperature = -1544; Console.Write("Number of Pages of the book: "); Console.WriteLine(NumberOfPages); Console.Write("Temperature to reach during the experiment: "); Console.Write(Temperature); Console.WriteLine(" degrees\n"); }
} This would produce:
Number of Pages of the book: 842 Temperature to reach during the experiment: -1544 degrees Because a short integer handles numbers that are larger than the signed byte, any variable you can declare for a signed byte can also be declared for a short variable.
Unsigned Short Integers If a variable must hold positive and relatively small numbers, it is referred as an unsigned short integer. Such a variable can be declared using the ushort keyword. An unsigned short integer can hold numbers that range from 0 to 65535 and therefore can fit in 16 bits. Here is an example: using System; class NumericRepresentation { static void Main() { // These variables must hold only positive integers ushort NumberOfTracks;
30 ushort MusicCategory; NumberOfTracks = 16; MusicCategory = 2; Console.Write("This music album contains "); Console.Write(NumberOfTracks); Console.WriteLine(" tracks"); Console.Write("Music Category: "); Console.Write(MusicCategory); Console.WriteLine();
} }
This would produce: This music album contains 16 tracks Music Category: 2
Practical Learning: Using Unsigned Short Integers 1. To use unsigned short integers, change the file as follows: using System; class GeorgetownCleaningServices { static void Main() { ushort NumberOfShirts; ushort NumberOfPants; ushort NumberOfDresses; NumberOfShirts = 4; NumberOfPants = 0; NumberOfDresses = 3; Console.WriteLine("-/- Georgetown Cleaning Services -/-");
}
Console.WriteLine("========================"); Console.WriteLine("Item Type Qty"); Console.WriteLine("------------------------"); Console.Write("Shirts "); Console.WriteLine(NumberOfShirts); Console.Write("Pants "); Console.WriteLine(NumberOfPants); Console.Write("Dresses "); Console.WriteLine(NumberOfDresses); Console.WriteLine("========================"); Console.WriteLine(); }
2. Execute the program. This would produce: -/- Georgetown Cleaning Services -/========================
31 Item Type Qty -----------------------Shirts 4 Pants 0 Dresses 3 ======================== 3. Return to Visual C#
A Double-Word Introduction A double-word is a group of two consecutive Words. This means that a double-word combines 4 bytes or 32 bits. The bits, counted from right to left, start at 0 and end at 31.
The most right bit, bit 0, is called the Low Order bit or LO bit or LOBIT. The most left bit, bit 31, is called the High Order bit or HI bit or HIBIT. The other bits are called using their positions. The group of the first 8 bits (from bit 0 to bit 7), which is the right byte, is called the Low Order Byte, or LO Byte. It is sometimes referred to as LOBYTE. The group of the last 8 bits (from bit 24 to bit 31), which is the left byte, is called the High Order Byte, or HI Byte or HIBYTE. The other bytes are called by their positions. The group of the right 16 bits, or the right Word, is called the Low Order Word, or LO Word, or LOWORD. The group of the left 16 bits, or the left Word, is called the High Order Word, or HI Word, or HIWORD.
The minimum binary number you can represent with a double-word is 0. The minimum decimal value of a double-word is 0. To find out the maximum decimal value of a word, you can use the base 2 formula giving a 1 value to each bit:
32
2n-1 230 229 228 227 226 225 224 etc 1,073,741,824 536,870,912 268,435,456 134,217,728 67,108,864 33,554,432 16,777,216 223 222 221 220 219 8,388,608 4,194,304 2,097,152 1,048,576 524,288
218 262,144
217 131,072
216 65,536
215 32,768
214 16,384
213 8,192
212 4,096
211 2,048
210 1,024
29 512
28 256
27 128
26 64
25 32
24 16
23 8
22 4
21 2
20 1
1*231+1*230+1*229 + 1*228 + 1*227 + 1*226 + 1*225 + 1*224 + 1*223 + 1*222 + 1*221 + 1*220 + 1*219 + 1*218 + 1*217 + 1*216 + 1*215 + 1*214 + 1*213 + 1*212 + 1*211 + 1*210 + 1*29 + 1*28 + 1*27 + 1*26 + 1*25 + 1*24 + 1*23 + 1*22 + 1*21 + 1*20 = 2,147,483,648 + 1,073,741,824 + 536,870,912 + 268,435,456 + 134,217,728 + 67,108,864 + 33,554,432 + 16,777,216 + 8,388,608 + 4,194,304 + 2,097,152 + 1,048,576 + 524,288 + 262,144 + 131,072 + 65,536 + 32,768 + 16,384 + 8,192 + 4,096 + 2,048 + 1,024 + 512 + 256 + 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 4,286,578,708 The minimum hexadecimal value you can store in a double-word is 0x00000000000000000000000000000000 which is the same as 0x0. To find out the maximum hexadecimal number you can represent with a word, replace every group of 4-bits with an f or F: 1111 1111 1111 1111 1111 1111 1111 1111 f f f f f f f f = 0xffffffff = 0Xffffffff = 0XFFFFFFFF = 0xFFFFFFFF
Signed Integers A double-word is large enough to contain double the amount of data that can be stored in a word. This is equivalent to 32 bits or 4 bytes or 4,294,967,295. Therefore, a double-word is used for large numbers that would not fit in a word. To use a variable that would hold quite large numbers, declare it using the int keyword. A variable declared as int can store values between –2,147,483,648 and 2,147,484,647 negative or positive, that can fit in 32 bits. Here is an example: using System; class NumericRepresentation
33 { static void Main() { int CoordX; int CoordY; CoordX = 12; CoordY = -8; Console.Write("Cartesian Coordinate System: "); Console.Write("P("); Console.Write(CoordX); Console.Write(", "); Console.Write(CoordY); Console.WriteLine(")\n"); }
} When executed, the program would produce:
Cartesian Coordinate System: P(12, -8)
Unsigned Integers If the variable must hold only positive natural numbers, you can declare it using the uint keyword. The uint keyword is used to identify a 32-bit positive integer whose value would range from 0 to 4,294,967,295. Here is an example: using System; class NumericRepresentation { static void Main() { uint DayOfBirth; uint MonthOfBirth; uint YearOfBirth; DayOfBirth = 8; MonthOfBirth = 11; YearOfBirth = 1996;
}
Console.WriteLine("Red Oak High School"); Console.Write("Student Date of Birth: "); Console.Write(MonthOfBirth); Console.Write("/"); Console.Write(DayOfBirth); Console.Write("/"); Console.Write(YearOfBirth); Console.WriteLine();
} This would produce: Red Oak High School Student Date of Birth: 11/8/1996
34
Practical Learning: Using Unsigned Integers 1. To unsigned unsigned variables, change the file as follows: using System; namespace GeorgetownCleaners { class OrderProcessing { static void Main() { ushort NumberOfShirts; ushort NumberOfPants; ushort NumberOfDresses; uint OrderDay; uint OrderMonth; uint OrderYear; NumberOfShirts = 4; NumberOfPants = 0; NumberOfDresses = 3; OrderDay = 15; OrderMonth = 7; OrderYear = 2002; Console.WriteLine("-/- Georgetown Cleaning Services -/-");
} }
Console.WriteLine("========================"); Console.Write("Order Date: "); Console.Write(OrderMonth); Console.Write('/'); Console.Write(OrderDay); Console.Write('/'); Console.WriteLine(OrderYear); Console.WriteLine("------------------------"); Console.WriteLine("Item Type Qty"); Console.WriteLine("------------------------"); Console.Write("Shirts "); Console.WriteLine(NumberOfShirts); Console.Write("Pants "); Console.WriteLine(NumberOfPants); Console.Write("Dresses "); Console.WriteLine(NumberOfDresses); Console.WriteLine("========================"); Console.WriteLine();
}
2. Execute the program. This would produce: -/- Georgetown Cleaning Services -/========================
35 Order Date: 7/15/2002 -----------------------Item Type Qty -----------------------Shirts 4 Pants 0 Dresses 3 ======================== 3. Return to Visual C#
A Quad-Word Introduction Sometimes you may want to store values that a double-word cannot handle. To store a very large number in a variable, you can consider a combination of 64 bits. The group can also be referred to as a quad-word. A quad-word is so large it can store numbers in the range of –9,223,372,036,854,775,808 and 9,223,372,036,854,775,807.
Long Integers To use a variable that can hold very large numbers that would require up to 64 bits, declare it using the long keyword. This is for a number that can range between –9,223,372,036,854,775,808 and 9,223,372,036,854,775,807. In C++, the long data type is 32 bits while in C#, the long data type is 64 bits. Here is an example that uses the long data type: using System; class NumericRepresentation { static void Main() { long CountryArea; CountryArea = 5638648; Console.Write("Country Area: "); Console.Write(CountryArea); Console.Write("km2\n"); }
} This would produce:
Country Area: 5638648km2 Although the long data type is used for large number, it mainly indicates the amount of space available but you don't have to use the whole space. For example, you can use the long keyword to declare a variable that would hold the same range of numbers as the short, the int, or the uint data types. If you declare a variable as long but use it for small numbers that don't require 64 bits, the compiler
36
would allocate the appropriate amount of space to accommodate the values of the variable. Consequently, the amount of space made available may not be as large as 64 bits. If you insist and want the compiler to reserve 64 bits, when assigning a value to the variable, add an l or an L suffix to it. Here is an example that uses space of a long data type to store a number that would fit in 32 bits: using System; class NumericRepresentation { static void Main() { long CountryArea; CountryArea = 5638648L; Console.Write("Country Area: "); Console.Write(CountryArea); Console.Write("km2\n"); }
} Therefore, keep in mind that an int, a uint, a short, or a ushort can fit in a long variable.
Unsigned Long Integers You can use a combination of 64 bits to store positive or negative integers. In some cases, you will need a variable to hold only positive, though large, numbers. To declare such a variable, you can use the ulong data type. A variable declared as ulong can handle extremely positive numbers that range from 0 to 18,446,744,073,709,551,615 to fit in 64 bits.
Real Numbers Introduction A real number is a number that displays a decimal part. This means that the number can be made of two sections separated by a symbol that is referred to as the Decimal Separator or Decimal Symbol. This symbol is different by language, country, group of languages, or group of countries. In US English, this symbol is the period as can be verified from the Regional (and Language) Settings of the Control Panel:
37
On both sides of the Decimal Symbol, digits are used to specify the value of the number. The number of digits on the right side of the symbol determines how much precision the number offers.
Single-Precision Numbers The integers we have used so far have the main limitation of not allowing decimal values. C# provides floating-point values that would solve this problem. The most fundamental floating variable is declared with the float keyword. A variable declared with float can store real numbers that range from ±1.5 × 10−45 to ±3.4 × 1038 with a precision of 7 digits in 32 bits. Here is an example: using System; class NumericRepresentation { static void Main() { float Distance; } }
Double-Precision Numbers
38
When a variable is larger than the float can handle and requires more precision, you should declare it using the double keyword. A variable declared as double uses 64 bits to store very large numbers ranging from ±5.0 × 10−324 to ±1.7 × 10308 with a precision of 15 or 16 digits. Here is an example: using System; class NumericRepresentation { static void Main() { double StudentAge; StudentAge = 14.50;
}
Console.Write("Student Age: "); Console.Write(StudentAge); Console.WriteLine();
} This would produce: Student Age: 14.5
Practical Learning: Using a Double-Precision Variable 1. To use a double-precision value, change the file as follows: using System; namespace GeorgetownCleaners { class OrderProcessing { static void Main() { ushort NumberOfShirts; ushort NumberOfPants; ushort NumberOfDresses; uint OrderDay; uint OrderMonth; uint OrderYear; double MondayDiscount; NumberOfShirts = 4; NumberOfPants = 0; NumberOfDresses = 3; OrderDay = 15; OrderMonth = 7; OrderYear = 2002;
39 MondayDiscount
= 0.25; // 25%
Console.WriteLine("-/- Georgetown Cleaning
Services -/-");
Console.WriteLine("========================"); Console.Write("Order Date: "); Console.Write(OrderMonth); Console.Write('/'); Console.Write(OrderDay); Console.Write('/'); Console.WriteLine(OrderYear); Console.WriteLine("------------------------"); Console.WriteLine("Item Type Qty"); Console.WriteLine("------------------------"); Console.Write("Shirts "); Console.WriteLine(NumberOfShirts); Console.Write("Pants "); Console.WriteLine(NumberOfPants); Console.Write("Dresses "); Console.WriteLine(NumberOfDresses); Console.WriteLine("------------------------"); Console.Write("Monday Discount: "); Console.Write(MondayDiscount); Console.WriteLine('%'); Console.WriteLine("========================"); Console.WriteLine(); }
} } 2. Save the file
Decimal The decimal data type can be used to declare a variable that would hold significantly large values that can be stored in a combination of 128 bits. You declare such a variable using the decimal keyword. The values stored in a decimal variable can range from ±1.0 × 10−28 to ±7.9 × 1028 with a precision of 28 to 29 digits. Because of this high level of precision, the decimal data type is suitable for currency values. After declaring a decimal variable, you can initialize it with a natural number. Here is an example: using System; class NumericRepresentation { static void Main() { decimal HourlySalary; HourlySalary = 24; Console.Write("Hourly Salary = "); Console.WriteLine(HourlySalary); Console.WriteLine(); }
}
40
This would produce: Hourly Salary = 24
Initializing a Real Number Because the double data type provides a better result with a better precision than the float, whenever you declare a variable as float and assign it a value as we did earlier, the compiler allocates 64 bits to store the values of the variable. If you insist on the variable being treated as float, when assigning it a value, add an f or an F suffix to the value. Here is an example: using System; class NumericRepresentation { static void Main() { float Distance; Distance = 248.38F;
}
Console.Write("Distance = "); Console.Write(Distance); Console.WriteLine("km\n");
} This would produce: Distance = 248.38km Otherwise, if you declare a double variable, when initializing it, to make sure the value is treated as double, type the d or the D suffix to the right of the value. If you declare a variable using the decimal keyword, to indicate that the variable holds a decimal value, when initializing it, add an m or an M suffix to its value.
Practical Learning: Using Decimal Values 1. To use decimal variables, change the file as follows: using System; namespace GeorgetownCleaners { class OrderProcessing { static void Main() { ushort NumberOfShirts; ushort NumberOfPants; ushort NumberOfDresses; decimal PriceOneShirt; decimal PriceAPairOfPants;
41 decimal PriceOneDress; uint OrderDay; uint OrderMonth; uint OrderYear; double MondayDiscount; NumberOfShirts NumberOfPants NumberOfDresses OrderDay OrderMonth OrderYear PriceOneShirt PriceAPairOfPants PriceOneDress MondayDiscount
= = = = = = = = = =
1; 1; 1; 15; 7; 2002; 0.95M; 2.95M; 4.55M; 0.25; // 25%
Console.WriteLine("-/- Georgetown Cleaning Services -/-");
} }
Console.WriteLine("========================"); Console.Write("Order Date: "); Console.Write(OrderMonth); Console.Write('/'); Console.Write(OrderDay); Console.Write('/'); Console.WriteLine(OrderYear); Console.WriteLine("------------------------"); Console.WriteLine("Item Type Qty Sub-Total"); Console.WriteLine("------------------------"); Console.Write("Shirts "); Console.Write(NumberOfShirts); Console.Write(" "); Console.WriteLine(PriceOneShirt); Console.Write("Pants "); Console.Write(NumberOfPants); Console.Write(" "); Console.WriteLine(PriceAPairOfPants); Console.Write("Dresses "); Console.Write(NumberOfDresses); Console.Write(" "); Console.WriteLine(PriceOneDress); Console.WriteLine("------------------------"); Console.Write("Monday Discount: "); Console.Write(MondayDiscount); Console.WriteLine('%'); Console.WriteLine("========================"); Console.WriteLine();
}
2. Execute the program. This would produce: -/- Georgetown Cleaning Services -/-
42 ======================== Order Date: 7/15/2002 -----------------------Item Type Qty Sub-Total -----------------------Shirts 1 0.95 Pants 1 2.95 Dresses 1 4.55 -----------------------Monday Discount: 0.25% ======================== 3. Return to Visual C#
.NET Support of Data Types Introduction All of the data types we have used so far are in fact complete classes. This means that they are equipped to handle their own assignments called functions as we will learn in subsequent lessons. When a data type (in this case a class) has to ability to perform assignments through its functions, it is able to better communicate with other variables, functions, or classes (the fact that the other languages, namely C/C++, Pascal, etc, use data types that are not considered classes doesn't mean they are less efficient or that they have an anomaly: it is simply the construct of the language!). These classes are defined in the System namespace. The classes of these data types are defined as: Data Type bool byte short int long float decimal
Class Boolean Byte Int16 Int32 Int64 Single Decimal
Data Type char sbyte ushort uint ulong double
Class Char SByte UInt16 UInt32 UInt64 Double
This means that, if you don't want to use the data types we have reviewed so far, you can use the class that is defined in the System namespace. To use one of these types, type the System namespace followed by a period. Then type the equivalent class you want to use. Here is an example: class Operations { public double Addition() { System.Double a; System.Double b; System.Double c; a = 128.76; b = 5044.52; c = a + b; }
return c;
43 } Because the regular names of data types we introduced in the previous lesson are more known and familiar, we will mostly use them. Because the data type are defined as classes, they are equipped with methods. One of the methods that each one them has is called ToString. As it s name implies, it is used to convert a value to a string.
Strings A string is an empty space, a character, a word, or a group of words that you want the compiler to consider "as is", that is, not to pay too much attention to what the string is made of, unless you explicitly ask it to. This means that, in the strict sense, you can put in a string anything you want. Primarily, the value of a string starts with a double quote and ends with a double-quote. An example of a string is "Welcome to the World of C# Programming!". You can include such a string in the Console.Write() method to display it on the console. Here is an example: using System; class BookClub { static void Main() { Console.WriteLine("Welcome to the World of C# Programming!"); } } This would produce: Welcome to the World of C# Programming! Sometimes, you will need to use a string whose value is not known in advance. Therefore, you can first declare a string variable. To do this, use the string keyword (in fact, it is a class) followed by a name for the variable. The name will follow the rules we defined above. An example of a string declaration is: string Msg; After declaring a string, you can give it a primary value by assigning it an empty space, a character, a symbol, a word, or a group of words. The value given to a string must be included in double-quotes. Here are examples of string variables declared and initialized: string string string string
Empty Gender FName Msg
= = = =
""; "F"; "Nelson Mandela"; "Welcome to the World of C# Programming! ";
After initializing a string variable, you can use its name in any valid operation or expression. For example, you can display its value on the console using the Console.Write() or the Console.WriteLine() methods. Here is an example: using System; class BookClub { static void Main()
44 { string Msg = "Welcome to the World of C# Programming! "; Console.WriteLine(Msg); }
}
Practical Learning: Using Strings 1. To use strings, change the file as follows: using System; namespace GeorgetownCleaners { class OrderProcessing { static void Main() { string CustomerName; string CustomerHomePhone; ushort NumberOfShirts; ushort NumberOfPants; ushort NumberOfDresses; decimal PriceOneShirt; decimal PriceAPairOfPants; decimal PriceOneDress; uint OrderDay; uint OrderMonth; uint OrderYear; double MondayDiscount; CustomerName = "Gregory Almas"; CustomerHomePhone = "(301) 723-4425"; NumberOfShirts NumberOfPants NumberOfDresses OrderDay OrderMonth OrderYear PriceOneShirt PriceAPairOfPants PriceOneDress MondayDiscount
= = = = = = = = = =
1; 1; 1; 15; 7; 2002; 0.95M; 2.95M; 4.55M; 0.25; // 25%
Console.WriteLine("-/- Georgetown Cleaning Services -/-");
Console.WriteLine("========================"); Console.Write("Customer: "); Console.WriteLine(CustomerName); Console.Write("Home Phone: "); Console.WriteLine(CustomerHomePhone);
45
} }
Console.Write("Order Date: "); Console.Write(OrderMonth); Console.Write('/'); Console.Write(OrderDay); Console.Write('/'); Console.WriteLine(OrderYear); Console.WriteLine("------------------------"); Console.WriteLine("Item Type Qty Sub-Total"); Console.WriteLine("------------------------"); Console.Write("Shirts "); Console.Write(NumberOfShirts); Console.Write(" "); Console.WriteLine(PriceOneShirt); Console.Write("Pants "); Console.Write(NumberOfPants); Console.Write(" "); Console.WriteLine(PriceAPairOfPants); Console.Write("Dresses "); Console.Write(NumberOfDresses); Console.Write(" "); Console.WriteLine(PriceOneDress); Console.WriteLine("------------------------"); Console.Write("Monday Discount: "); Console.Write(MondayDiscount); Console.WriteLine('%'); Console.WriteLine("========================"); Console.WriteLine();
}
2. Execute the program. This would produce:
46
3. Return to Visual C#
Dates and Times A date is a unit that measures the number of years, months, or days elapsed in a specific period. A time is a unit that counts the number of seconds that have elapsed since midnight of the day considered. Although dates and times are large subjects that would require a detailed study, at this time, we will consider them in simple terms. To declare a variable that would hold date or time values, use the DateTime data type (like every data type we have used so far, except the string that is a class, DateTime is a structure). using System; class NumericRepresentation { static void Main() { DateTime DateHired; } } The .NET Framework sets its starting periodic date to January 1, 0001 at midnight (12:00:00 or 0:00 AM). If not assigned a specific value (in future lessons, we will learn that this is equivalent to declaring a variable using the default constructor), the variable is initialized to 1/1/0001 at midnight.
Objects The Object data type (it is a class) is used to declare a variable whose type is not primarily defined and can be any of the other data types we have introduced. Here is an example: using System; class Exercise { static void Main() { object Whatever; } }
47
Operators and Operands Fundamental C# Operators Introduction An operation is an action performed on one or more values either to modify the value held by one or both of the variables, or to produce a new value by combining existing values. Therefore, an operation is performed using at least one symbol and at least one value. The symbol used in an operation is called an operator. A value involved in an operation is called an operand. A unary operator is an operator that performs its operation on only one operand. An operator is referred to as binary if it operates on two operands.
Semi-Colon;
48
The semi-colon is used to indicate the end of an expression or a declaration. Here is an example: using System; As we will learn when studying the for conditional statement, there are other uses of the semicolon.
Practical Learning: Introducing the Semi-Colon 1. Start Microsoft Visual C# or Visual Studio .NET 2. On the main menu, click File -> New -> Project 3. If necessary, in the Project Types list of the New Project dialog box, click Visual C# Projects 4. In the Templates list, click Empty Project
5. In the Name text box, replace the name with GCS2 and specify the desired path in the Location
6. Click OK 7. To create a source file for the project, on the main menu, click Project -> Add New Item... 8. In the Add New Item dialog box, in the Templates list, click Code File
9. In the Name text box, delete the suggested name and replace it with Exercise 10. Click Open 11. In the empty file, type the following: using System; 12. To execute the application, on the main menu, click Debug -> Start Without Debugging 13. Press Enter to close the DOS window and return to Visual C#
Curly Brackets { } Curly brackets are probably the most used and the most tolerant operators of C#. Fundamentally, curly brackets are used to create a section of code. As such they are required to delimit the bodies of namespaces, classes, structures, exceptions, etc. They are also optionally used in conditional statements. Curly brackets are also used to create variable scope. Here is an example: using System; class Exercise { }
Practical Learning: Using Curly Brackets 1. To use curly brackets, change the file as follows: using System;
49 namespace GeorgetownCleaningServices { } 2. Save the file
Parentheses ( ) Like most computer languages, C# uses parentheses to isolate a group of items that must be considered as belonging to one entity. For example, parentheses are used to differentiate a method such as Main from a regular variable. Here is an example: using System; class Exercise { static void Main() { } } Parentheses can also be used to isolate an operation or an expression with regard to another operation or expression.
Practical Learning: Using Parentheses 1. To use parentheses, change the file as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { static void Main() { double MondayDiscount; } } } 2. Save the file
The Comma , The comma is used to separate variables used in a group. For example, a comma can be used to delimit the names of variables that are declared with the same data type. Here is an example: using System; class Exercise { static void Main() { string FirstName, LastName, FullName; }
50 } The comma can also be used to separate the member of an enumerator or the arguments of a method. We will review all of them when the time comes.
Practical Learning: Using Commas 1. To use commas, change the file as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { static void Main() { string CustomerName, HomePhone; uint NumberOfShirts, NumberOfPants, NumberOfDresses; decimal PriceOneShirt, PriceAPairOfPants, PriceOneDress; uint OrderMonth, OrderDay, OrderYear; double MondayDiscount; } } } 2. Save the file
The Assignment = When you declare a variable, a memory space is reserved for it. That memory space may be empty until you fill it with a value. To "put" a value in the memory space allocated to a variable, you can use the assignment operator represented as =. Based on this, the assignment operation gives a value to a variable. Its syntax is: VariableName = Value The VariableName factor must be a valid variable name. It cannot be a value such as a numeric value or a (double-quoted) string. Here is an example that assigns a numeric value to a variable: namespace Operations { class Exercise { static void Main() { decimal Salary; // Using the assignment operator Salary = 12.55M; } }
}
51
Once a variable has been declared and assigned a value, you can call Write() or WriteLine() to display its value. Here is an example: namespace Operations { class Exercise { static void Main() { decimal Salary; // Using the assignment operator Salary = 12.55M; System.Console.Write("Employee's Hourly Salary: "); System.Console.WriteLine(Salary); }
}
} This would produce: Employee's Hourly Salary: $12.55 The above code declares a variable before assigning it a value. You will usually perform this assignment when you want to change the value held by a variable. Providing a starting value to a variable when the variable is declared is referred to as initializing the variable. Here is an example: namespace Operations { class Exercise { static void Main() { // Using the assignment operator decimal Salary = 12.55M; System.Console.Write("Employee's Hourly Salary: "); System.Console.WriteLine(Salary); }
}
} We saw that you can declare various variables at once by using the same data type but separating their names with commas. When doing this, you can also initialize each variable by assigning it the desired value before the comma or the semi-colon. Here is an example: namespace Operations { class Exercise { static void Main() { // Initializing various variables when declaring them with the same data type double Value1 = 224.58, Value2 = 1548.26;
52 System.Console.Write("Value 1 = "); System.Console.WriteLine(Value1); System.Console.Write("Value 2 = "); System.Console.WriteLine(Value2); System.Console.WriteLine();
} }
}
This would produce: Value 1 = 224.58 Value 2 = 1548.26
Practical Learning: Assigning Values to Variables 1. To use the assignment operator, change the file as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { static void Main() { string CustomerName, HomePhone; uint NumberOfShirts = 5, NumberOfPants = 2, NumberOfDresses = 0; decimal PriceOneShirt = 0.95M, PriceAPairOfPants = 2.95M, PriceOneDress = 4.55M; uint OrderMonth = 3, OrderDay = 15, OrderYear = 2002; double MondayDiscount = 0.25; // 25%; } }
Console.WriteLine();
}
2. Save the file
Single-Quote ' The single quote is used to include one character to initialize, or assign a symbol to, a variable declared as char. A single is usually combined with another and a character is included between them. Here is an example: using System; class Exercise { static void Main() {
53 char Gender; string FirstName, LastName, FullName; }
Gender = 'M';
} You can include only one character between single-quotes except if the combination of symbols can be evaluated to one character. This is the case for escape sequences. Here is an example: using System; class Exercise { static void Main() { Console.WriteLine('\n'); } }
Double-Quotes " The double-quote " is used to delimit a string. Like the single-quote, the double-quote is usually combined with another. Between the combination of double-quotes, you can include an empty space, a character, a word, or a group of words, making it a string. Here is an example: using System; class Exercise { static void Main() { Console.WriteLine("The Wonderful World of C#!!!"); } } A double-quoted string can also be declared and then assigned to a variable.
Practical Learning: Using Quotes 1. To use single and double-quotes, change the file as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { static void Main() { string CustomerName = "James Burreck", HomePhone = "(202) 301-7030"; uint NumberOfShirts = 1, NumberOfPants = 1, NumberOfDresses = 1; decimal PriceOneShirt = 0.95M, PriceAPairOfPants = 2.95M,
54 PriceOneDress = 4.55M; uint OrderMonth = 3, OrderDay = 15, OrderYear = 2002; double MondayDiscount = 0.25; // 25%; Console.WriteLine("-/- Georgetown Cleaning Services -/-");
} }
Console.WriteLine("========================"); Console.Write("Customer: "); Console.WriteLine(CustomerName); Console.Write("Home Phone: "); Console.WriteLine(HomePhone); Console.Write("Order Date: "); Console.Write(OrderMonth); Console.Write('/'); Console.Write(OrderDay); Console.Write('/'); Console.WriteLine(OrderYear); Console.WriteLine("------------------------"); Console.WriteLine("Item Type Qty Sub-Total"); Console.WriteLine("------------------------"); Console.Write("Shirts "); Console.Write(NumberOfShirts); Console.Write(" "); Console.WriteLine(PriceOneShirt); Console.Write("Pants "); Console.Write(NumberOfPants); Console.Write(" "); Console.WriteLine(PriceAPairOfPants); Console.Write("Dresses "); Console.Write(NumberOfDresses); Console.Write(" "); Console.WriteLine(PriceOneDress); Console.WriteLine("------------------------"); Console.Write("Monday Discount: "); Console.Write(MondayDiscount); Console.WriteLine('%'); Console.WriteLine("========================"); Console.WriteLine();
}
2. To execute the program, on the main menu, click Debug -> Start Without Debugging. This would produce:
55
3. Return to Visual C#
Square Brackets [ ] Square brackets are mostly used to control the dimension or index of an array. We will learn how to use them when we study arrays. Here is an example from a future lesson: using System; namespace CSharpLessons { class Exercise { static void Main() { double[] number = new double[5]; number[0] number[1] number[2] = 6.28; number[3] number[4]
= 12.44; = 525.38; = 2448.32; = 632.04;
Console.WriteLine(); }
}
}
The Positive Operator + Algebra uses a type of ruler to classify numbers. This ruler has a middle position of zero. The numbers on the left side of the 0 are referred to as negative while the numbers on the right
56
side of the rulers are considered positive: -∞
-6
-5
-4
-3
-2
-1
1
2
3
4
5
6
+∞
1
2
3
4
5
6
+∞
0 -∞
-6
-5
-4
-3
-2
-1
A value on the right side of 0 is considered positive. To express that a number is positive, you can write a + sign on its left. Examples are +4, +228, +90335. In this case the + symbol is called a unary operator because it acts on only one operand. The positive unary operator, when used, must be positioned on the left side of its operand, never on the right side. As a mathematical convention, when a value is positive, you don't need to express it with the + operator. Just writing the number without any symbol signifies that the number is positive. Therefore, the numbers +4, +228, and +90335 can be, and are better, expressed as 4, 228, 90335. Because the value doesn't display a sign, it is referred as unsigned. To express a variable as positive or unsigned, you can just type it. here is an example: using System; class Exercise { static void Main() { // Displaying an unsigned number Console.Write("Number = "); Console.WriteLine(+802); } } This would produce: Number = 802
The Negative Operator As you can see on the above ruler, in order to express any number on the left side of 0, it must be appended with a sign, namely the - symbol. Examples are -12, -448, -32706. A value accompanied by - is referred to as negative. The - sign must be typed on the left side of the number it is used to negate. Remember that if a number does not have a sign, it is considered positive. Therefore, whenever a number is negative, it MUST have a - sign. In the same way, if you want to change a value from positive to negative, you can just add a - sign to its left. Here is an example that uses two variables. One has a positive value while the other has a negative value: using System; class Exercise { static void Main() { // Displaying an unsigned number Console.Write("First Number "); Console.WriteLine(+802);
57 // Displaying a negative number Console.Write("Second Number "); Console.WriteLine(-802); }
} This would produce:
First Number 802 Second Number -802
Unary Operators: The sizeof Operator We have already seen that when declaring a variable, the compiler reserves a portion of space in the computer memory to hold that variable. We also illustrated how much space some data types need to store their variable. C++ provides the unary sizeof operator that allows you to find out how much space a data type. You can use the sizeof operator as unsafe in your C# application. To find out how much memory space a data type uses, type it between the parentheses of the sizeof operator. Remember that sizeof is unsafe. Therefore, a method that uses it must be preceded with the unsafe keyword. Here is an example: using System; class Exercise { unsafe static void Main() { // The sizeof operator used to get the memory size used by // a variable declared with a certain a data type Console.WriteLine("The sizeof Operator"); Console.WriteLine("=========================="); Console.WriteLine("Data Type Memory Size"); Console.WriteLine("--------------------------"); Console.Write("char "); Console.Write(sizeof(char)); Console.WriteLine(" Bytes"); Console.Write("bool "); Console.Write(sizeof(bool)); Console.WriteLine(" Bytes"); Console.Write("int "); Console.Write(sizeof(int)); Console.WriteLine(" Bytes"); Console.Write("uint "); Console.Write(sizeof(uint)); Console.WriteLine(" Bytes"); Console.Write("short "); Console.Write(sizeof(short)); Console.WriteLine(" Bytes"); Console.Write("ushort "); Console.Write(sizeof(ushort)); Console.WriteLine(" Bytes"); Console.Write("byte "); Console.Write(sizeof(byte)); Console.WriteLine(" Bytes");
58 Console.Write("sbyte "); Console.Write(sizeof(sbyte)); Console.WriteLine(" Bytes"); Console.Write("float "); Console.Write(sizeof(float)); Console.WriteLine(" Bytes"); Console.Write("double "); Console.Write(sizeof(double)); Console.WriteLine(" Bytes"); Console.Write("decimal "); Console.Write(sizeof(decimal)); Console.WriteLine(" Bytes"); Console.Write("long "); Console.Write(sizeof(long)); Console.WriteLine(" Bytes"); Console.Write("ulong "); Console.Write(sizeof(ulong)); Console.WriteLine(" Bytes"); Console.WriteLine("==========================="); Console.WriteLine(); }
} This
would
produce:
The sizeof Operator ========================== Data Type Memory Size -------------------------char 2 Bytes bool 1 Bytes int 4 Bytes uint 4 Bytes short 2 Bytes ushort 2 Bytes byte 1 Bytes sbyte 1 Bytes float 4 Bytes double 8 Bytes decimal 16 Bytes long 8 Bytes ulong 8 Bytes ===========================
Algebraic Operators In algebra, operations are performed on numeric values. Algebraic operators are represented with the following symbols:
The Addition
59
The addition is an operation used to add things of the same nature one to another, as many as necessary. Sometimes, the items are added one group to another. The concept is still the same, except that this last example is faster. The addition is performed in mathematics using the + sign. The same sign is used in C#. To get the addition of two values, you add the first one to the other. After the addition of two values has been performed, you get a new value. This means that if you add Value1 to Value2, you would write Value1 + Value2. The result is another value we could call Value3. You can also add more than two values, like a + b + c. With numbers, the order you use to add two or more values doesn't matter. This means that Value1 + Value2 is the same as Value2 + Value1. In the same way a + b + c is the same as a + c + b the same as b + a + c and the same as c + b + a Here is an example that adds two numbers: namespace Operations { class Exercise { static void Main() { System.Console.Write("244 + 835 = "); System.Console.WriteLine(244 + 835); } } } Here is the result: 244 + 835 = 1079 You can also add some values already declared and initialized in your program. You can also get the values from the user. In C#, you can also add string variables to add a new string. The operation is performed as if you were using numbers. For example, "Pie" + "Chart" would produce "PieChart". You can also add add as many strings as possible by including the + operator between them. Here is an example: namespace Operations { class Exercise { static void Main() { string FirstName = "Alexander"; string LastName = "Kallack"; string FullName = FirstName + " " + LastName; System.Console.Write("Full Name: "); System.Console.WriteLine(FullName); } } } This would produce: Full Name: Alexander Kallack
60
Practical Learning: Using the Addition Operator 1. To use the addition, change the file as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { static void Main() { string CustomerName = "James Burreck", HomePhone = "(202) 301-7030"; uint NumberOfShirts = 1, NumberOfPants = 1, NumberOfDresses = 1; uint TotalNumberOfItems; decimal PriceOneShirt = 0.95M, PriceAPairOfPants = 2.95M, PriceOneDress = 4.55M; uint OrderMonth = 3, OrderDay = 15, OrderYear = 2002; TotalNumberOfItems = NumberOfShirts + NumberOfPants + NumberOfDresses; Console.WriteLine("-/- Georgetown Cleaning Services -/-"); Console.WriteLine("========================"); Console.Write("Customer: "); Console.WriteLine(CustomerName); Console.Write("Home Phone: "); Console.WriteLine(HomePhone); Console.Write("Order Date: "); Console.Write(OrderMonth); Console.Write('/'); Console.Write(OrderDay); Console.Write('/'); Console.WriteLine(OrderYear); Console.WriteLine("------------------------"); Console.WriteLine("Item Type Qty Sub-Total"); Console.WriteLine("------------------------"); Console.Write("Shirts "); Console.Write(NumberOfShirts); Console.Write(" "); Console.WriteLine(PriceOneShirt); Console.Write("Pants "); Console.Write(NumberOfPants); Console.Write(" "); Console.WriteLine(PriceAPairOfPants); Console.Write("Dresses "); Console.Write(NumberOfDresses); Console.Write(" "); Console.WriteLine(PriceOneDress); Console.WriteLine("------------------------"); Console.Write("Number of Items: "); Console.WriteLine(TotalNumberOfItems);
61 Console.WriteLine("========================"); Console.WriteLine(); }
} }
2. Execute the program. This would produce: -/- Georgetown Cleaning Services -/======================== Customer: James Burreck Home Phone: (202) 301-7030 Order Date: 3/15/2002 -----------------------Item Type Qty Sub-Total -----------------------Shirts 1 0.95 Pants 1 2.95 Dresses 1 4.55 -----------------------Number of Items: 3 ======================== 3. Return to Visual C#
The Multiplication The multiplication allows adding one value to itself a certain number of times, set by a second value. As an example, instead of adding a value to itself in this manner: A + A + A + A, since the variable a is repeated over and over again, you could simply find out how many times A is added to itself, then multiply a by that number which, is this case, is 4. This would mean adding a to itself 4 times, and you would get the same result. Just like the addition, the multiplication is associative: a * b * c = c * b * a. When it comes to programming syntax, the rules we learned with the addition operation also apply to the multiplication. Here is an example: namespace Operations { class Exercise { static void Main() { // Initializing various variables when declaring them with the same data type double Value1 = 224.58, Value2 = 1548.26; double Result = Value1 * Value2;
}
System.Console.Write(Value1); System.Console.Write(" * "); System.Console.Write(Value2); System.Console.Write(" = "); System.Console.WriteLine(Result); System.Console.WriteLine();
62
}
} This would produce:
224.58 * 1548.26 = 347708.2308
Practical Learning: Using the Multiplication Operator 1. To multiply, change the file as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { static void Main() { const decimal PriceOneShirt = 0.95M; const decimal PriceAPairOfPants = 2.95M; const decimal PriceOneDress = 4.55M; string CustomerName = "James Burreck", HomePhone = "(202) 301-7030"; uint NumberOfShirts = 5, NumberOfPants = 2, NumberOfDresses = 3; uint TotalNumberOfItems; decimal SubTotalShirts, SubTotalPants, SubTotalDresses; decimal TotalOrder; uint OrderMonth = 3, OrderDay = 15, OrderYear = 2002; TotalNumberOfItems = NumberOfShirts + NumberOfPants + NumberOfDresses; SubTotalShirts = PriceOneShirt * NumberOfShirts; SubTotalPants = PriceAPairOfPants * NumberOfPants; SubTotalDresses = NumberOfDresses * PriceOneDress; TotalOrder = SubTotalShirts + SubTotalPants + SubTotalDresses; Console.WriteLine("-/- Georgetown Cleaning Services -/-"); Console.WriteLine("===================================="); Console.Write("Customer: "); Console.WriteLine(CustomerName); Console.Write("Home Phone: "); Console.WriteLine(HomePhone); Console.Write("Order Date: "); Console.Write(OrderMonth); Console.Write('/'); Console.Write(OrderDay); Console.Write('/'); Console.WriteLine(OrderYear); Console.WriteLine("------------------------------------"); Console.WriteLine("Item Type Qty Unit/Price Sub-Total"); Console.WriteLine("------------------------------------"); Console.Write("Shirts "); Console.Write(NumberOfShirts); Console.Write(" ");
63
} }
Console.Write(PriceOneShirt); Console.Write(" "); Console.WriteLine(SubTotalShirts); Console.Write("Pants "); Console.Write(NumberOfPants); Console.Write(" "); Console.Write(PriceAPairOfPants); Console.Write(" "); Console.WriteLine(SubTotalPants); Console.Write("Dresses "); Console.Write(NumberOfDresses); Console.Write(" "); Console.Write(PriceOneDress); Console.Write(" "); Console.WriteLine(SubTotalDresses); Console.WriteLine("------------------------------------"); Console.Write("Number of Items: "); Console.WriteLine(TotalNumberOfItems); Console.Write("Total Order: "); Console.WriteLine(TotalOrder); Console.WriteLine("===================================="); Console.WriteLine();
}
2. Execute the program. This would produce: -/- Georgetown Cleaning Services -/==================================== Customer: James Burreck Home Phone: (202) 301-7030 Order Date: 3/15/2002 -----------------------------------Item Type Qty Unit/Price Sub-Total -----------------------------------Shirts 5 0.95 4.75 Pants 2 2.95 5.90 Dresses 3 4.55 13.65 -----------------------------------Number of Items: 10 Total Order: 24.30 ==================================== 3. Return to Visual C#
The Subtraction The subtraction operation is used to take out or subtract a value from another value. It is essentially the opposite of the addition. The subtraction is performed with the - sign. Here is an example: using System; namespace Operations
64 { class Exercise { static void Main() { // Values used in this program double Value1 = 224.58, Value2 = 1548.26; double Result = Value1 - Value2;
} }
Console.Write(Value1); Console.Write(" - "); Console.Write(Value2); Console.Write(" = "); Console.WriteLine(Result);
} This would produce:
224.58 - 1548.26 = -1323.68 Unlike the addition, the subtraction is not associative. In other words, a - b - c is not the same as c - b - a. Consider the following program that illustrates this: using System; namespace Operations { class Exercise { static void Main() { // This tests whether the addition is associative Console.WriteLine(" =+= Addition =+="); Console.Write("128 + 42 + 5 = "); Console.WriteLine(128 + 42 + 5); Console.Write(" 5 + 42 + 128 = "); Console.WriteLine(5 + 42 + 128); Console.WriteLine(); // This tests whether the subtraction is associative Console.WriteLine(" =-= Subtraction =-="); Console.Write("128 - 42 5 = "); Console.WriteLine(128 - 42 - 5); Console.Write(" 5 - 42 - 128 = "); Console.WriteLine(5 - 42 - 128); } }
} This would produce:
=+= Addition =+=
Console.WriteLine();
65 128 + 42 + 5 = 175 5 + 42 + 128 = 175 =-= Subtraction =-= 128 - 42 5 = 81 5 - 42 - 128 = -165 Notice that both operations of the addition convey the same result. In the subtraction section, the numbers follow the same order but produce different results.
Practical Learning: Using the Subtraction Operator 1. To Subtract, change the file as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { static void Main() { const decimal const decimal const decimal const decimal
PriceOneShirt PriceAPairOfPants PriceOneDress SalesTaxRate
= = = =
0.95M; 2.95M; 4.55M; 0.0575M; // 5.75%
string CustomerName = "James Burreck", HomePhone = "(202) 301-7030"; uint NumberOfShirts = 5, NumberOfPants = 2, NumberOfDresses = 3; uint TotalNumberOfItems; decimal SubTotalShirts, SubTotalPants, SubTotalDresses; decimal TaxAmount, TotalOrder, NetPrice; uint OrderMonth = 3, OrderDay = 15, OrderYear = 2002; NumberOfDresses;
TotalNumberOfItems = NumberOfShirts + NumberOfPants + SubTotalShirts SubTotalPants SubTotalDresses TotalOrder
SubTotalDresses;
= = = =
PriceOneShirt * NumberOfShirts; PriceAPairOfPants * NumberOfPants; NumberOfDresses * PriceOneDress; SubTotalShirts + SubTotalPants +
TaxAmount = TotalOrder * SalesTaxRate; NetPrice = TotalOrder - TaxAmount; Console.WriteLine("-/- Georgetown Cleaning Services -/-"); Console.WriteLine("===================================="); Console.Write("Customer: "); Console.WriteLine(CustomerName); Console.Write("Home Phone: "); Console.WriteLine(HomePhone); Console.Write("Order Date: "); Console.Write(OrderMonth); Console.Write('/');
66
} }
Console.Write(OrderDay); Console.Write('/'); Console.WriteLine(OrderYear); Console.WriteLine("------------------------------------"); Console.WriteLine("Item Type Qty Unit/Price Sub-Total"); Console.WriteLine("------------------------------------"); Console.Write("Shirts "); Console.Write(NumberOfShirts); Console.Write(" "); Console.Write(PriceOneShirt); Console.Write(" "); Console.WriteLine(SubTotalShirts); Console.Write("Pants "); Console.Write(NumberOfPants); Console.Write(" "); Console.Write(PriceAPairOfPants); Console.Write(" "); Console.WriteLine(SubTotalPants); Console.Write("Dresses "); Console.Write(NumberOfDresses); Console.Write(" "); Console.Write(PriceOneDress); Console.Write(" "); Console.WriteLine(SubTotalDresses); Console.WriteLine("------------------------------------"); Console.Write("Number of Items: "); Console.WriteLine(TotalNumberOfItems); Console.Write("Total Order: "); Console.WriteLine(TotalOrder); Console.Write("Tax Rate: "); Console.Write(SalesTaxRate * 100); Console.WriteLine('%'); Console.Write("Tax Amount: "); Console.WriteLine(TaxAmount); Console.Write("Net Price: "); Console.WriteLine(NetPrice); Console.WriteLine("===================================="); Console.WriteLine();
}
2. Execute the program. This would produce: -/- Georgetown Cleaning Services -/==================================== Customer: James Burreck Home Phone: (202) 301-7030 Order Date: 3/15/2002 -----------------------------------Item Type Qty Unit/Price Sub-Total -----------------------------------Shirts 5 0.95 4.75 Pants 2 2.95 5.90 Dresses 3 4.55 13.65 ------------------------------------
67 Number of Items: 10 Total Order: 24.30 Discount Rate: 12.500% Discount Amount: 3.03750 Net Price: 21.26250 ==================================== 3. Return to Visual C#
The Division Dividing an item means cutting it in pieces or fractions of a set value. For example, when you cut an apple in the middle, you are dividing it in 2 pieces. If you cut each one of the resulting pieces, you will get 4 pieces or fractions. This is considered that you have divided the apple in 4 parts. Therefore, the division is used to get the fraction of one number in terms of another. The division is performed with the forward slash /. Here is an example: namespace Operations { class Exercise { static void Main() { // Initializing various variables when declaring them with the same data type double Value1 = 224.58, Value2 = 1548.26; double Result = Value1 / Value2; System.Console.Write(Value1); System.Console.Write(" / "); System.Console.Write(Value2); System.Console.Write(" = "); System.Console.WriteLine(Result); System.Console.WriteLine(); }
}
} This would produce: 224.58 / 1548.26 = 0.145053156446592 When performing the division, be aware of its many rules. Never divide by zero (0). Make sure that you know the relationship(s) between the numbers involved in the operation.
Practical Learning: Using the Division Operator 1. To use the division, change the file as follows: using System; namespace GeorgetownCleaningServices {
68 class OrderProcessing { static void Main() { const decimal const decimal const decimal const decimal const decimal
SalesTotal;
PriceOneShirt PriceAPairOfPants PriceOneDress DiscountRate TaxRate
= = = = =
0.95M; 2.95M; 4.55M; 0.20M; // 20% 5.75M; // 5.75%
string CustomerName = "James Burreck", HomePhone = "(202) 301-7030"; uint NumberOfShirts = 5, NumberOfPants = 2, NumberOfDresses = 3; uint TotalNumberOfItems; decimal SubTotalShirts, SubTotalPants, SubTotalDresses; decimal DiscountAmount, TotalOrder, NetPrice, TaxAmount, decimal AmountTended, Difference; uint OrderMonth = 3, OrderDay = 15, OrderYear = 2002; TotalNumberOfItems = NumberOfShirts + NumberOfPants +
NumberOfDresses;
SubTotalDresses;
SubTotalShirts SubTotalPants SubTotalDresses TotalOrder
= = = =
PriceOneShirt * NumberOfShirts; PriceAPairOfPants * NumberOfPants; NumberOfDresses * PriceOneDress; SubTotalShirts + SubTotalPants +
DiscountAmount NetPrice TaxAmount SalesTotal AmountTended Difference
= = = = = =
TotalOrder * DiscountRate; TotalOrder - DiscountAmount; TotalOrder * TaxRate / 100; NetPrice + TaxAmount; 50M; AmountTended - SalesTotal;
Console.WriteLine("-/- Georgetown Cleaning Services -/-"); Console.WriteLine("===================================="); Console.Write("Customer: "); Console.WriteLine(CustomerName); Console.Write("Home Phone: "); Console.WriteLine(HomePhone); Console.Write("Order Date: "); Console.Write(OrderMonth); Console.Write('/'); Console.Write(OrderDay); Console.Write('/'); Console.WriteLine(OrderYear); Console.WriteLine("------------------------------------"); Console.WriteLine("Item Type Qty Unit/Price Sub-Total"); Console.WriteLine("------------------------------------"); Console.Write("Shirts "); Console.Write(NumberOfShirts); Console.Write(" "); Console.Write(PriceOneShirt); Console.Write(" ");
69 Console.WriteLine(SubTotalShirts); Console.Write("Pants "); Console.Write(NumberOfPants); Console.Write(" "); Console.Write(PriceAPairOfPants); Console.Write(" "); Console.WriteLine(SubTotalPants); Console.Write("Dresses "); Console.Write(NumberOfDresses); Console.Write(" "); Console.Write(PriceOneDress); Console.Write(" "); Console.WriteLine(SubTotalDresses); Console.WriteLine("------------------------------------"); Console.Write("Number of Items: "); Console.WriteLine(TotalNumberOfItems); Console.Write("Total Order: "); Console.WriteLine(TotalOrder); Console.Write("Discount Rate: "); Console.Write(DiscountRate * 100); Console.WriteLine('%'); Console.Write("Discount Amount: "); Console.WriteLine(DiscountAmount); Console.Write("After Discount: "); Console.WriteLine(NetPrice); Console.Write("Tax Rate: "); Console.Write(TaxRate); Console.WriteLine('%'); Console.Write("Tax Amount: "); Console.WriteLine(TaxAmount); Console.Write("Net Price: "); Console.WriteLine(SalesTotal); Console.WriteLine("===================================="); Console.Write("Amount Tended: "); Console.WriteLine(AmountTended); Console.Write("Difference: "); Console.WriteLine(Difference); Console.WriteLine("===================================="); } }
}
Console.WriteLine();
70 2. Execute the program. This would produce:
3. Return to Visual C#
The Remainder The division program above will give you a result of a number with decimal values if you type an odd number (like 147), which is fine in some circumstances. Sometimes you will want to get the value remaining after a division renders a natural result. Imagine you have 26 kids at a football (soccer) stadium and they are about to start. You know that you need 11 kids for each team to start. If the game starts with the right amount of players, how many will seat and wait? The remainder operation is performed with the percent sign (%) which is gotten from pressing Shift + 5. Here is an example: // Program used to perform the remainder operation. using System; class Exercise { static void Main() { int Players = 26; // When the game starts, how many players will wait?. Console.Write("Out of "); Console.Write(Players); Console.Write(" players, ");
71
}
Console.Write(26 % 11); Console.WriteLine(" players will have to wait when the game starts.\n");
} This would produce: Out of 26 players, 4 players will have to wait when the game starts.
C# Language Operators Increment ++ Introduction We are used to counting numbers such as 1, 2, 3, 4, etc. In reality, when counting such numbers, we are simply adding 1 to a number in order to get the next number in the range. The simplest technique of incrementing a value consists of adding 1 to it. After adding 1, the value or the variable is (permanently) modified and the variable would hold the new value. This is illustrated in the following example: // This program studies value incrementing using System; class Exercise { static void Main() { int Value = 12; Console.WriteLine("Techniques of incrementing a value"); Console.Write("Value = "); Console.WriteLine(Value); Value = Value + 1;
}
Console.Write("Value = "); Console.WriteLine(Value);
} This would produce: Techniques of incrementing a value Value = 12 Value = 13 C# provides a special operator that takes care of this operation. The operator is called the increment operator and is represented by ++. Instead of writing Value = Value + 1, you can write Value++ and you would get the same result. The above program can be re-written as follows: // This program studies value incrementing using System; class Exercise
72 {
static void Main() { int Value = 12; Console.WriteLine("Techniques of incrementing a value"); Console.Write("Value = "); Console.WriteLine(Value); Value++;
}
Console.Write("Value = "); Console.WriteLine(Value);
} The ++ is a unary operator because it operates on only one variable. It is used to modify the value of the variable by adding 1 to it. Every time the Value++ is executed, the compiler takes the previous value of the variable, adds 1 to it, and the variable holds the incremented value: // This program studies value incrementing using System; class Exercise { static void Main() { int Value = 12; Console.WriteLine("Techniques of incrementing a value"); Value++; Console.Write("Value = "); Console.WriteLine(Value); Value++; Console.Write("Value = "); Console.WriteLine(Value); Value++; Console.Write("Value = "); Console.WriteLine(Value); }
} This would produce:
Techniques of incrementing a value Value = 13 Value = 14 Value = 15
Pre and Post-Increment When using the ++ operator, the position of the operator with regard to the variable it is
73
modifying can be significant. To increment the value of the variable before re-using it, you should position the operator on the left of the variable: // This program studies value incrementing using System; class Exercise { static void Main() { int Value = 12; Console.WriteLine("Techniques of incrementing a value"); Console.Write("Value = "); Console.WriteLine(Value); Console.Write("Value = "); Console.WriteLine(++Value);
}
Console.Write("Value = "); Console.WriteLine(Value);
} This would produce: Techniques of incrementing a value Value = 12 Value = 13 Value = 13 When writing ++Value, the value of the variable is incremented before being called. On the other hand, if you want to first use a variable, then increment it, in other words, if you want to increment the variable after calling it, position the increment operator on the right side of the variable: // This program studies value incrementing using System; class Exercise { static void Main() { int Value = 12; Console.WriteLine("Techniques of incrementing a value"); Console.Write("Value = "); Console.WriteLine(Value); Console.Write("Value = "); Console.WriteLine(Value++); Console.Write("Value = ");
74
}
Console.WriteLine(Value);
} This would produce: Techniques of incrementing a value Value = 12 Value = 12 Value = 13
Decrement -Introduction When counting numbers backward, such as 8, 7, 6, 5, etc, we are in fact subtracting 1 from a value in order to get the lesser value. This operation is referred to as decrementing a value. This operation works as if a value is decremented by 1, as in Value = Value – 1: // This program studies value decrementing using System; class Exercise { static void Main() { int Value = 12; Console.WriteLine("Techniques of decrementing a value"); Console.Write("Value = "); Console.WriteLine(Value); Value = Value - 1;
}
Console.Write("Value = "); Console.WriteLine(Value);
} This would produce: Techniques of decrementing a value Value = 12 Value = 11 As done to increment, C# provides a quicker way of subtracting 1 from a value. This is done using the decrement operator, that is --. To use the decrement operator, type –- on the left or the right side of the variable when this operation is desired. Using the decrement operator, the above program could be written: // This program studies value decrementing using System; class Exercise { static void Main() {
75 int Value = 12; Console.WriteLine("Techniques of decrementing a value"); Console.Write("Value = "); Console.WriteLine(Value); Value--;
}
Console.Write("Value = "); Console.WriteLine(Value);
} Pre-Decrement Once again, the position of the operator can be important. If you want to decrement the variable before calling it, position the decrement operator on the left side of the operand. This is illustrated in the following program: // This program studies value decrementing using System; class Exercise { static void Main() { int Value = 12; Console.WriteLine("Techniques of decrementing a value"); Console.Write("Value = "); Console.WriteLine(Value); Console.Write("Value = "); Console.WriteLine(--Value);
}
Console.Write("Value = "); Console.WriteLine(Value);
} This would produce: Techniques of decrementing a value Value = 12 Value = 11 Value = 11 If you plan to decrement a variable only after it has been accessed, position the operator on the right side of the variable. Here is an example: // This program studies value decrementing using System; class Exercise { static void Main() {
76 int Value = 12; Console.WriteLine("Techniques of decrementing a value"); Console.Write("Value = "); Console.WriteLine(Value); Console.Write("Value = "); Console.WriteLine(Value--); Console.Write("Value = "); Console.WriteLine(Value); }
} This would produce:
Techniques of decrementing a value Value = 12 Value = 12 Value = 11
Techniques of Incrementing and Decrementing a Variable It is not unusual to add or subtract a constant value to or from a variable. All you have to do is to declare another variable that would hold the new value. Here is an example: // This program studies value incrementing and decrementing using System; class Exercise { static void Main() { double Value = 12.75; double NewValue; Console.WriteLine("Techniques of incrementing and decrementing a value");
Console.Write("Value = "); Console.WriteLine(Value); NewValue = Value + 2.42; Console.Write("Value = "); Console.WriteLine(NewValue);
}
} This would produce:
Techniques of incrementing and decrementing a value Value = 12.75 Value = 15.17 The above technique requires that you use an extra variable in your application. The advantage is that each value can hold its own value although the value of the second variable depends on whatever would happen to the original or source variable.
77
Sometimes in your program you will not need to keep the original value of the source variable. You may want to permanently modify the value that a variable is holding. In this case you can perform the addition operation directly on the variable by adding the desired value to the variable. This operation modifies whatever value a variable is holding and does not need an additional variable. To add a value to a variable and change the value that the variable is holding, you can combine the assignment “=” and the addition “+” operators to produce a new operator as += Here is an example: // This program studies value incrementing and decrementing using System; class Exercise { static void Main() { double Value = 12.75; value");
Console.WriteLine("Techniques of incrementing and decrementing a Console.Write("Value = "); Console.WriteLine(Value); Value += 2.42;
}
Console.Write("Value = "); Console.WriteLine(Value);
} This program produces the same result as the previous. To decrement the value of a variable, instead of the addition, use the subtraction and apply the same technique. In the above program, the variable can have its value decremented by combining the assignment and the subtraction operations on the variable. This is done with the -= operator. Here is an example: // This program studies value incrementing and decrementing using System; class Exercise { static void Main() { double Value = 12.75; value");
Console.WriteLine("Techniques of incrementing and decrementing a Console.Write("Value = "); Console.WriteLine(Value); Value -= 2.42;
}
Console.Write("Value = "); Console.WriteLine(Value);
78 } This would produce: Techniques of incrementing and decrementing a value Value = 12.75 Value = 10.33
Operator Precedence and Direction When combining operations in C#, there are two aspects involved: an operator's precedence and its direction. If you ask the compiler to add two numbers, for example 240 + 65, it will execute the operation by adding 240 to 65. In other words, it would read 240, then +, then 65, and evaluate the result. This is considered as operating from left to right: 240 -> + -> 65. This process is referred to as the direction of the operation. As you will regularly combine operators on your various calculations, each operation is known for how much it "weighs" as compared to other operators. This is known as its precedence. This means that when a certain operator is combined with another, such as a + b * c, or x / y z, some operators would execute before others, almost regardless of how you write the operation. That's why an operator could be categorized by its level of precedence. One way you can avoid being concerned by the level of precedence of operator is by using parentheses to tell the compiler how to proceed with the operations, that is, what operation should (must) be performed first. Consider the following algebraic operation: 154 - 12 + 8 The question here is to know whether you want to subtract the addition of 12 and 8 from 154 or you want to add the difference between 154 and 12 to 8. Using parentheses, you can communicate your intentions to the compiler. This is illustrated in the following program: using System; class Exercise { static void Main() { int Operation1 = (154 - 12) + 8; int Operation2 = 154 - (12 + 8); operation");
}
Console.Write("Examining the effect of the parentheses in an Console.Write("\n(154 - 12) + 8 = "); Console.Write(Operation1); Console.Write("\n154 - (12 + 8) = "); Console.Write(Operation2); Console.WriteLine();
} This would produce: Examining the effect of the parentheses in an operation (154 - 12) + 8 = 150 154 - (12 + 8) = 134 As you can see, using the parentheses controls how the whole operation would proceed. This
79
difference can be even more accentuated if your operation includes 3 or more operators and 4 or more operands.
Data Reading and Formatting Data Reading Introduction In previous lessons, we saw that the Console class allows using the Write() and the WriteLine() functions to display things on the screen. While the Console.Write() method is used to display something on the screen, the Console class provides the Read() method to get a value from the user. To use it, the name of a variable can be assigned to it. The syntax used
80
is: VariableName = Console.Read(); This simply means that, when the user types something and presses Enter, what the user had typed would be given (the word is assigned) to the variable specified on the left side of the assignment operator. Read() doesn't always have to assign its value to a variable. For example, it can be used on its own line, which simply means that the user is expected to type something but the value typed by the user would not be used for any significant purpose. For example some versions of C# (even including Microsoft's C# and Borland C#Builder) would display the DOS window briefly and disappear. You can use the Read() function to wait for the user to press any key in order to close the DOS window. Besides Read(), the Console class also provides the ReadLine() method. Like the WriteLine() member function, after performing its assignment, the ReadLine() method sends the caret to the next line. Otherwise, it plays the same role as the Read() function.
Practical Learning: Introducing Data Reading 1. Start Microsoft Visual C# or Visual Studio .NET 2. On the main menu, click File -> New -> Project 3. If necessary, in the Project Types list of the New Project dialog box, click Visual C# Projects 4. In the Templates list, click Empty Project
5. In the Name text box, replace the name with GCS3 and specify the desired path in the Location
6. Click OK 7. To create a source file for the project, on the main menu, click Project -> Add New Item... 8. In the Add New Item dialog box, in the Templates list, click Code File
9. In the Name text box, delete the suggested name and replace it with Exercise 10. Click Open 11. In the empty file, type the following: using System; namespace GeorgetownCleaningServices { class OrderProcessing { static void Main() { Console.WriteLine(); } } } 12. To execute the application, on the main menu, click Debug -> Start Without Debugging
81
String Value Request In most assignments of your programs, you will not know the value of a string when writing your application. For example, you may want the user to provide such a string. To request a string (or any of the variables we will see in this lesson), you can call the Console.Read() or the Console.ReadLine() function and assign it to the name of the variable whose value you want to retrieve. Here is an example: string FirstName; Console.Write("Enter First Name: "); FirstName = Console.ReadLine();
Practical Learning: Reading String Values 1. To request strings from the user, change the file as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { static void Main() { string CustomerName, HomePhone; Console.WriteLine("-/- Georgetown Cleaning Services -/-"); // Request customer information from the user Console.Write("Enter Customer Name: "); CustomerName = Console.ReadLine(); Console.Write("Enter Customer Phone: "); HomePhone = Console.ReadLine();
} }
Console.WriteLine(); // Display the receipt Console.WriteLine("===================================="); Console.WriteLine("-/- Georgetown Cleaning Services -/-"); Console.WriteLine("===================================="); Console.Write("Customer: "); Console.WriteLine(CustomerName); Console.Write("Home Phone: "); Console.WriteLine(HomePhone); Console.WriteLine("====================================\n");
}
2. To execute the program, on the main menu, click Debug -> Start Without Debugging. This would produce: -/- Georgetown Cleaning Services -/Enter Customer Name: James Watson Enter Customer Phone: (410) 493-2005
82 ==================================== -/- Georgetown Cleaning Services -/==================================== Customer: James Watson Home Phone: (410) 493-2005 ====================================
3. Return to Visual C# notepad
Number Request In C#, everything the user types is a string and the compiler would hardly analyze it without your explicit asking it to do so. Therefore, if you want to get a number from the user, first request a string. Here is an example: using System; namespace GeorgetownCleaningServices { class OrderProcessing { static void Main() { int Number; string strNumber; strNumber = Console.ReadLine(); }
}
} After getting the string, you must convert it to a number. To perform this conversion, each data type of the .NET Framework provides a mechanism called Parse. To use Parse(), type the data type, followed by a period, followed by Parse, and followed by parentheses. In the parentheses of Parse, type the string that you requested from the user. Here is an example: using System; namespace GeorgetownCleaningServices { class OrderProcessing { static void Main() { int Number; string strNumber; strNumber = Console.ReadLine(); Number = int.Parse(strNumber); }
}
} An advanced but faster way to do this is to type Console.ReadLine() in the parentheses of
83
Parse. This has the same effect. Here is an example: using System; namespace GeorgetownCleaningServices { class OrderProcessing { static void Main() { int Number; Number = int.Parse(Console.ReadLine()); }
}
}
Practical Learning: Reading Numeric Values 1. To retrieve various numbers from the user, change the file as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { static void Main() { // Price of items const decimal PriceOneShirt const decimal PriceAPairOfPants const decimal PriceOneDress const decimal TaxRate
= = = =
0.95M; 2.95M; 4.55M; 0.0575M;
// 5.75%
// Customer personal infoirmation string CustomerName, HomePhone; // Unsigned numbers to represent cleaning items uint NumberOfShirts, NumberOfPants, NumberOfDresses; // Each of these sub totals will be used for cleaning items decimal SubTotalShirts, SubTotalPants, SubTotalDresses; // Values used to process an order decimal TotalOrder, TaxAmount, SalesTotal; decimal AmountTended, Difference; Console.WriteLine("-/- Georgetown Cleaning Services -/-"); // Request customer information from the user Console.Write("Enter Customer Name: "); CustomerName = Console.ReadLine(); Console.Write("Enter Customer Phone: "); HomePhone = Console.ReadLine();
84 // Request the quantity of each category of items Console.Write("Number of Shirts: "); string strShirts = Console.ReadLine(); NumberOfShirts = uint.Parse(strShirts); Console.Write("Number of Pants: "); string strPants = Console.ReadLine(); NumberOfPants = uint.Parse(strPants); Console.Write("Number of Dresses: "); string strDresses = Console.ReadLine(); NumberOfDresses = uint.Parse(strDresses); // Perform the necessary calculations SubTotalShirts = NumberOfShirts * PriceOneShirt; SubTotalPants = NumberOfPants * PriceAPairOfPants; SubTotalDresses = NumberOfDresses * PriceOneDress; // Calculate the "temporary" total of the order TotalOrder = SubTotalShirts + SubTotalPants + SubTotalDresses; // Calculate the tax amount using a constant rate TaxAmount = TotalOrder * TaxRate; // Add the tax amount to the total order SalesTotal = TotalOrder + TaxAmount; // Communicate the total to the user... Console.Write("\nThe Total order is: "); Console.WriteLine(SalesTotal); // and request money for the order Console.Write("Amount Tended? "); AmountTended = decimal.Parse(Console.ReadLine()); // Calculate the difference owed to the customer // or that the customer still owes to the store Difference = AmountTended - SalesTotal; Console.WriteLine(); // Display the receipt Console.WriteLine("===================================="); Console.WriteLine("-/- Georgetown Cleaning Services -/-"); Console.WriteLine("===================================="); Console.Write("Customer: "); Console.WriteLine(CustomerName); Console.Write("Home Phone: "); Console.WriteLine(HomePhone); Console.WriteLine("------------------------------------"); Console.WriteLine("Item Type Qty Unit/Price Sub-Total"); Console.WriteLine("------------------------------------"); Console.Write("Shirts "); Console.Write(NumberOfShirts); Console.Write(" "); Console.Write(PriceOneShirt); Console.Write(" "); Console.WriteLine(SubTotalShirts); Console.Write("Pants ");
85 Console.Write(NumberOfPants); Console.Write(" "); Console.Write(PriceAPairOfPants); Console.Write(" "); Console.WriteLine(SubTotalPants); Console.Write("Dresses "); Console.Write(NumberOfDresses); Console.Write(" "); Console.Write(PriceOneDress); Console.Write(" "); Console.WriteLine(SubTotalDresses); Console.WriteLine("------------------------------------"); Console.Write("Total Order: "); Console.WriteLine(TotalOrder); Console.Write("Tax Rate: "); Console.Write(TaxRate * 100); Console.WriteLine('%'); Console.Write("Tax Amount: "); Console.WriteLine(TaxAmount); Console.Write("Net Price: "); Console.WriteLine(SalesTotal); Console.WriteLine("------------------------------------"); Console.Write("Amount Tended: "); Console.WriteLine(AmountTended); Console.Write("Difference: "); Console.WriteLine(Difference); Console.WriteLine("===================================="); }
}
} 2. Save the file 3. At the Command Prompt, change to the GCS3 folder
4. To compile the program, type csc /out:"Georgetown Cleaning Services".exe Exercise.cs and press Enter
5. To execute the program, type "Georgetown Cleaning Services" and press Enter. Here is an example of running the program:
-/- Georgetown Cleaning Services -/Enter Customer Name: Genevieve Alton Enter Customer Phone: (202) 974-8244 Number of Shirts: 8 Number of Pants: 2 Number of Dresses: 3 The Total order is: 28.711125 Amount Tended? 30 ==================================== -/- Georgetown Cleaning Services -/==================================== Customer: Genevieve Alton Home Phone: (202) 974-8244 ------------------------------------
86 Item Type Qty Unit/Price Sub-Total -----------------------------------Shirts 8 0.95 7.60 Pants 2 2.95 5.90 Dresses 3 4.55 13.65 -----------------------------------Total Order: 27.15 Tax Rate: 5.7500% Tax Amount: 1.561125 Net Price: 28.711125 -----------------------------------Amount Tended: 30 Difference: 1.288875 ==================================== 6. Return to Notepad
Requesting Dates and Times As done with the regular numbers, you can request a date value from the user. This is also done by requesting a string from the user. Here is an example: using System; namespace ValueRequests { class Exercise { static void Main() { string strDateHired; strDateHired = Console.ReadLine(); }
}
} After the user has entered the string you can then convert it to a DateTime value. Just like any value you request from the user, a date or time value that the user types must be valid, otherwise, the program would produce an error. Because dates and times follow some rules for their formats, you should strive to let the user know how you expect the value to be entered. By default, if you request only a date from the user and the user enters a valid date, the compiler would add the midnight value to the date. If you request only the time from the user and the user enters a valid time, the compiler would add the current date to the value. Later on, we will learn how to isolate either only the date or only the time.
Practical Learning: Requesting Date and Time Values 1. To deal with new dates and times, change the program as follows: using System; namespace GeorgetownCleaningServices {
87 class OrderProcessing { static void Main() { // Price of items const decimal PriceOneShirt const decimal PriceAPairOfPants const decimal PriceOneDress const decimal TaxRate
= = = =
0.95M; 2.95M; 4.55M; 0.0575M;
// 5.75%
// Basic information about an order string CustomerName, HomePhone; DateTime OrderDate; // Unsigned numbers to represent cleaning items uint NumberOfShirts, NumberOfPants, NumberOfDresses; // Each of these sub totals will be used for cleaning items decimal SubTotalShirts, SubTotalPants, SubTotalDresses; // Values used to process an order decimal TotalOrder, TaxAmount, SalesTotal; decimal AmountTended, Difference;
AM/PM)");
Console.WriteLine("-/- Georgetown Cleaning Services -/-"); // Request order information from the user Console.Write("Enter Customer Name: "); CustomerName = Console.ReadLine(); Console.Write("Enter Customer Phone: "); HomePhone = Console.ReadLine(); Console.WriteLine("Enter the order date and time (mm/dd/yyyy hh:mm OrderDate = DateTime.Parse(Console.ReadLine()); // Request the quantity of each category of items Console.Write("Number of Shirts: "); string strShirts = Console.ReadLine(); NumberOfShirts = uint.Parse(strShirts); Console.Write("Number of Pants: "); string strPants = Console.ReadLine(); NumberOfPants = uint.Parse(strPants); Console.Write("Number of Dresses: "); string strDresses = Console.ReadLine(); NumberOfDresses = uint.Parse(strDresses);
SubTotalDresses;
// Perform the necessary calculations SubTotalShirts = NumberOfShirts * PriceOneShirt; SubTotalPants = NumberOfPants * PriceAPairOfPants; SubTotalDresses = NumberOfDresses * PriceOneDress; // Calculate the "temporary" total of the order TotalOrder = SubTotalShirts + SubTotalPants + // Calculate the tax amount using a constant rate TaxAmount = TotalOrder * TaxRate; // Add the tax amount to the total order SalesTotal = TotalOrder + TaxAmount;
88
// Communicate the total to the user... Console.Write("\nThe Total order is: "); Console.WriteLine(SalesTotal); // and request money for the order Console.Write("Amount Tended? "); AmountTended = decimal.Parse(Console.ReadLine()); // Calculate the difference owed to the customer // or that the customer still owes to the store Difference = AmountTended - SalesTotal; Console.WriteLine(); // Display the receipt Console.WriteLine("===================================="); Console.WriteLine("-/- Georgetown Cleaning Services -/-"); Console.WriteLine("===================================="); Console.Write("Customer: "); Console.WriteLine(CustomerName); Console.Write("Home Phone: "); Console.WriteLine(HomePhone); Console.Write("Date & Time: "); Console.WriteLine(OrderDate); Console.WriteLine("------------------------------------"); Console.WriteLine("Item Type Qty Unit/Price Sub-Total"); Console.WriteLine("------------------------------------"); Console.Write("Shirts "); Console.Write(NumberOfShirts); Console.Write(" "); Console.Write(PriceOneShirt); Console.Write(" "); Console.WriteLine(SubTotalShirts); Console.Write("Pants "); Console.Write(NumberOfPants); Console.Write(" "); Console.Write(PriceAPairOfPants); Console.Write(" "); Console.WriteLine(SubTotalPants); Console.Write("Dresses "); Console.Write(NumberOfDresses); Console.Write(" "); Console.Write(PriceOneDress); Console.Write(" "); Console.WriteLine(SubTotalDresses); Console.WriteLine("------------------------------------"); Console.Write("Total Order: "); Console.WriteLine(TotalOrder); Console.Write("Tax Rate: "); Console.Write(TaxRate * 100); Console.WriteLine('%'); Console.Write("Tax Amount: "); Console.WriteLine(TaxAmount); Console.Write("Net Price: "); Console.WriteLine(SalesTotal); Console.WriteLine("------------------------------------"); Console.Write("Amount Tended: ");
89
} }
Console.WriteLine(AmountTended); Console.Write("Difference: "); Console.WriteLine(Difference); Console.WriteLine("====================================");
}
2. Save the file 3. At the Command Prompt, change to the GCS3 folder
4. To compile the program, type
csc /out:"Georgetown Cleaning Services".exe Exercise.cs and press Enter
5. To execute the program, type "Georgetown Cleaning Services" and press Enter. Here is an example of running the program: -/- Georgetown Cleaning Services -/Enter Customer Name: Alexander Pappas Enter Customer Phone: (301) 397-9764 Enter the order date and time (mm/dd/yyyy hh:mm AM/PM) 06/22/98 08:26 AM Number of Shirts: 2 Number of Pants: 6 Number of Dresses: 0 The Total order is: 20.727000 Amount Tended? 50 ==================================== -/- Georgetown Cleaning Services -/==================================== Customer: Alexander Pappas Home Phone: (301) 397-9764 Date & Time: 6/22/1998 8:26:00 AM -----------------------------------Item Type Qty Unit/Price Sub-Total -----------------------------------Shirts 2 0.95 1.90 Pants 6 2.95 17.70 Dresses 0 4.55 0 -----------------------------------Total Order: 19.60 Tax Rate: 5.7500% Tax Amount: 1.127000 Net Price: 20.727000 -----------------------------------Amount Tended: 50 Difference: 29.273000 ==================================== 6. Return to Notepad
Formatting Data Display Introduction
90
Instead of using two Write() or a combination of Write() and WriteLine() to display data, you can convert a value to a string and display it directly. To do this, you can provide two strings to the Write() or WriteLine() and separate them with a comma:
1. The first part of the string provided to Write() or WriteLine() is the complete string that would display to the user. This first string itself can be made of different sections: a. One section is a string in any way you want it to display b. Another section is a number included between an opening curly bracket "{" and a closing curly bracket "}". This combination of "{" and "}" is referred to as a placeholder You can put the placeholder anywhere inside of the string. The first placeholder must have number 0. The second must have number 1, etc. With this technique, you can create the string anyway you like and use the placeholders anywhere inside of the string
2. The second part of the string provided to Write() or WriteLine() is the value that you want to display. It can be one value if you used only one placeholder with 0 in the first string. If you used different placeholders, you can then provide a different value for each one of them in this second part, separating the values with a comma Here are examples: using System; // An Exercise class class Exercise { static void Main() { String FullName = "Anselme Bogos"; int Age = 15; double HSalary = 22.74; Console.WriteLine("Full Name: {0}", FullName); Console.WriteLine("Age: {0}", Age); Console.WriteLine("Distance: {0}", HSalary); Console.WriteLine(); }
} This would produce:
Full Name: Anselme Bogos Age: 15 Distance: 22.74 As mentioned already, the numeric value typed in the curly brackets of the first part is an ordered number. If you want to display more than one value, provide each incremental value in its curly brackets. The syntax used is: Write("To Display {0} {1} {2} {n}", First, Second, Third, nth); You can use the sections between a closing curly bracket and an opening curly bracket to
91
create a meaningful sentence.
Practical Learning: Displaying Data With Placeholders 1. To use curly brackets to display data, change the file as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { static void Main() { // Price of items const decimal PriceOneShirt const decimal PriceAPairOfPants const decimal PriceOneDress const decimal TaxRate
= = = =
0.95M; 2.95M; 4.55M; 0.0575M;
// 5.75%
// Basic information about an order string CustomerName, HomePhone; DateTime OrderDate; // Unsigned numbers to represent cleaning items uint NumberOfShirts, NumberOfPants, NumberOfDresses; // Each of these sub totals will be used for cleaning items decimal SubTotalShirts, SubTotalPants, SubTotalDresses; // Values used to process an order decimal TotalOrder, TaxAmount, SalesTotal; decimal AmountTended, Difference;
AM/PM)");
Console.WriteLine("-/- Georgetown Cleaning Services -/-"); // Request order information from the user Console.Write("Enter Customer Name: "); CustomerName = Console.ReadLine(); Console.Write("Enter Customer Phone: "); HomePhone = Console.ReadLine(); Console.WriteLine("Enter the order date and time (mm/dd/yyyy hh:mm OrderDate = DateTime.Parse(Console.ReadLine()); // Request the quantity of each category of items Console.Write("Number of Shirts: "); NumberOfShirts = uint.Parse(Console.ReadLine()); Console.Write("Number of Pants: "); NumberOfPants = uint.Parse(Console.ReadLine()); Console.Write("Number of Dresses: "); NumberOfDresses = uint.Parse(Console.ReadLine()); // Perform the necessary calculations SubTotalShirts = NumberOfShirts * PriceOneShirt; SubTotalPants = NumberOfPants * PriceAPairOfPants;
92 SubTotalDresses = NumberOfDresses * PriceOneDress; // Calculate the "temporary" total of the order TotalOrder = SubTotalShirts + SubTotalPants + SubTotalDresses; // Calculate the tax amount using a constant rate TaxAmount = TotalOrder * TaxRate; // Add the tax amount to the total order SalesTotal = TotalOrder + TaxAmount; // Communicate the total to the user... Console.Write("\nThe Total order is: "); Console.WriteLine(SalesTotal); // and request money for the order Console.Write("Amount Tended? "); AmountTended = decimal.Parse(Console.ReadLine()); // Calculate the difference owed to the customer // or that the customer still owes to the store Difference = AmountTended - SalesTotal; Console.WriteLine();
SubTotalDresses);
} }
// Display the receipt Console.WriteLine("===================================="); Console.WriteLine("-/- Georgetown Cleaning Services -/-"); Console.WriteLine("===================================="); Console.WriteLine("Customer: {0}", CustomerName); Console.WriteLine("Home Phone: {0}", HomePhone); Console.WriteLine("Date & Time: {0}", OrderDate); Console.WriteLine("------------------------------------"); Console.WriteLine("Item Type Qty Unit/Price Sub-Total"); Console.WriteLine("------------------------------------"); Console.WriteLine("Shirts {0} {1} {2}", NumberOfShirts, PriceOneShirt, SubTotalShirts); Console.WriteLine("Pants {0} {1} {2}", NumberOfPants, PriceAPairOfPants, SubTotalPants); Console.WriteLine("Dresses {0} {1} {2}", NumberOfDresses, PriceOneDress, Console.WriteLine("------------------------------------"); Console.WriteLine("Total Order: {0}", TotalOrder); Console.WriteLine("Tax Rate: {0}%", TaxRate * 100); Console.WriteLine("Tax Amount: {0}", TaxAmount); Console.WriteLine("Net Price: {0}", SalesTotal); Console.WriteLine("------------------------------------"); Console.WriteLine("Amount Tended: {0}", AmountTended); Console.WriteLine("Difference: {0}", Difference); Console.WriteLine("====================================");
}
2. Save, compile, and execute the program
Conversion To String We mentioned earlier that everything the user types using the keyboard is primarily a string
93
and it's your job to convert it to the appropriate type. In reverse, if you have a value that is not a string, you can easily convert it to a string. To support this, each .NET Framework data type provides a mechanism called ToString. Normally, in C#, as we mentioned with boxing, and as we have done so far, this conversion is automatically or transparently done by the compiler. In some cases, you will need to perform the conversion yourself. To conversion a value of a primitive data type to a string, type the name of the variable, followed by a period, followed, followed by ToString(). Here is an example: using System; // An Exercise class class Exercise { static void Main() { String FullName = "Anselme Bogos"; int Age = 15; double HSalary = 22.74; Console.WriteLine("Full Name: {0}", FullName); Console.WriteLine("Age: {0}", Age.ToString()); Console.WriteLine("Distance: {0}", HSalary.ToString()); }
Console.WriteLine();
} In some cases, you will type something in the parentheses of ToString().
Practical Learning: Converting to String 1. To convert some values to string, change the program as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { static void Main() { // Price of items const decimal PriceOneShirt const decimal PriceAPairOfPants const decimal PriceOneDress const decimal TaxRate
= = = =
0.95M; 2.95M; 4.55M; 0.0575M;
// 5.75%
. . . No Change Console.WriteLine("------------------------------------"); Console.WriteLine("Shirts {0} {1} {2}", NumberOfShirts.ToString(), PriceOneShirt, SubTotalShirts.ToString());
94 Console.WriteLine("Pants {0} {1} {2}", NumberOfPants, PriceAPairOfPants,
SubTotalPants);
Console.WriteLine("Dresses {0} {1} {2}", NumberOfDresses, PriceOneDress, SubTotalDresses);
TaxAmount.ToString());
} }
Console.WriteLine("------------------------------------"); Console.WriteLine("Total Order: {0}", TotalOrder); Console.WriteLine("Tax Rate: {0}%", TaxRate * 100); Console.WriteLine("Tax Amount: {0}", Console.WriteLine("Net Price: {0}", SalesTotal); Console.WriteLine("------------------------------------"); Console.WriteLine("Amount Tended: {0}", AmountTended); Console.WriteLine("Difference: {0}", Difference); Console.WriteLine("====================================");
}
2. Save, compile, and execute the program
Number Formatting To properly display data in a friendly and most familiar way, you can format it. Formatting tells the compiler what kind of data you are using and how you want the compiler to display it to the user. As it happens, you can display a natural number in a common value or, depending on the circumstance, you may prefer to show it as a hexadecimal value. When it comes to doubleprecision numbers, you may want to display a distance with three values on the right side of the decimal separator and in some cases, you may want to display a salary with only 2 decimal places. The System namespace provides a specific letter that you can use in the Write() or WriteLine()'s placeholder for each category of data to display. To format a value, in the placeholder of the variable or value, after the number, type a colon and one of the appropriate letter from the following table. If you are using ToString(), then, in the parentheses of ToString(), you can include a specific letter or combination inside of double-quotes. The letters and their meanings are: Character c C d D e E f F g G n N r R x X p P Here are examples: using System;
Used For Currency values Decimal numbers Scientific numeric display such as 1.45e5 Fixed decimal numbers General and most common type of numbers Natural numbers Roundtrip formatting Hexadecimal formatting Percentages
95
// An Exercise class class Exercise { static void Main() { double Distance = 248.38782; int Age = 15; int NewColor = 3478; double HSalary = 22.74, HoursWorked = 35.5018473; double WeeklySalary = HSalary * HoursWorked; Console.WriteLine("Distance: {0}", Distance.ToString("E")); Console.WriteLine("Age: {0}", Age.ToString()); Console.WriteLine("Color: {0}", NewColor.ToString("X")); Console.WriteLine("Weekly Salary: {0} for {1} hours", WeeklySalary.ToString("c"), HoursWorked.ToString("F")); Console.WriteLine(); }
} This would produce:
Distance: 2.483878E+002 Age: 15 Color: D96 Weekly Salary: $807.31 for 35.50 hours As you may have noticed, if you leave the parentheses of ToString() empty, the compiler would use a default formatting to display the value. As opposed to calling ToString(), you can use the above letters in the curly brackets of the first part of Write() or WriteLine(). In this case, after the number in the curly brackets, type the colon operator followed by the letter.
Practical Learning: Formatting Data Display 1. To format data display, change the file as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { static void Main() { // Price of items const decimal PriceOneShirt const decimal PriceAPairOfPants const decimal PriceOneDress const decimal TaxRate
= = = =
0.95M; 2.95M; 4.55M; 5.75M;
// Basic information about an order
// 5.75%
96 string CustomerName, HomePhone; DateTime OrderDate; // Unsigned numbers to represent cleaning items uint NumberOfShirts, NumberOfPants, NumberOfDresses; // Each of these sub totals will be used for cleaning items decimal SubTotalShirts, SubTotalPants, SubTotalDresses; // Values used to process an order decimal TotalOrder, TaxAmount, SalesTotal; decimal AmountTended, Difference; Console.WriteLine("-/- Georgetown Cleaning Services -/-"); // Request order information from the user Console.Write("Enter Customer Name: "); CustomerName = Console.ReadLine(); Console.Write("Enter Customer Phone: "); HomePhone = Console.ReadLine(); Console.WriteLine("Enter the order date and time (mm/dd/yyyy hh:mm AM/PM)");
OrderDate = DateTime.Parse(Console.ReadLine()); // Request the quantity of each category of items Console.Write("Number of Shirts: "); NumberOfShirts = uint.Parse(Console.ReadLine()); Console.Write("Number of Pants: "); NumberOfPants = uint.Parse(Console.ReadLine()); Console.Write("Number of Dresses: "); NumberOfDresses = uint.Parse(Console.ReadLine());
SubTotalDresses;
// Perform the necessary calculations SubTotalShirts = NumberOfShirts * PriceOneShirt; SubTotalPants = NumberOfPants * PriceAPairOfPants; SubTotalDresses = NumberOfDresses * PriceOneDress; // Calculate the "temporary" total of the order TotalOrder = SubTotalShirts + SubTotalPants + // Calculate the tax amount using a constant rate TaxAmount = TotalOrder * TaxRate; // Add the tax amount to the total order SalesTotal = TotalOrder + TaxAmount; // Communicate the total to the user... Console.Write("\nThe Total order is: "); Console.WriteLine(SalesTotal); // and request money for the order Console.Write("Amount Tended? "); AmountTended = decimal.Parse(Console.ReadLine()); // Calculate the difference owed to the customer // or that the customer still owes to the store Difference = AmountTended - SalesTotal; Console.WriteLine(); // Display the receipt
97 Console.WriteLine("===================================="); Console.WriteLine("-/- Georgetown Cleaning Services -/-"); Console.WriteLine("===================================="); Console.WriteLine("Customer: {0}", CustomerName); Console.WriteLine("Home Phone: {0}", HomePhone); Console.WriteLine("Date & Time: {0}", OrderDate); Console.WriteLine("------------------------------------"); Console.WriteLine("Item Type Qty Unit/Price Sub-Total"); Console.WriteLine("------------------------------------"); Console.WriteLine("Shirts {0} {1:C} {2}", NumberOfShirts.ToString(), PriceOneShirt, SubTotalShirts.ToString("C")); Console.WriteLine("Pants {0} {1:C} {2:C}", NumberOfPants, PriceAPairOfPants, SubTotalPants); Console.WriteLine("Dresses {0} {1:C} {2:C}", NumberOfDresses, PriceOneDress, SubTotalDresses);
Console.WriteLine("------------------------------------"); Console.WriteLine("Total Order: {0:C}", TotalOrder); Console.WriteLine("Tax Rate: {0:P}", TaxRate); Console.WriteLine("Tax Amount: {0}", TaxAmount.ToString("C")); Console.WriteLine("Net Price: {0:F}", SalesTotal); Console.WriteLine("------------------------------------"); Console.WriteLine("Amount Tended: {0:C}", AmountTended); Console.WriteLine("Difference: {0:C}", Difference); Console.WriteLine("===================================="); } } } 2. Save it and switch to the Command Prompt. Then compile the file and execute the application. Here is an example: -/- Georgetown Cleaning Services -/Enter Customer Name: Gretchen McCormack Enter Customer Phone: (410) 739-2884 Enter the order date and time (mm/dd/yyyy hh:mm AM/PM) 04/09/2001 10:25 AM Number of Shirts: 5 Number of Pants: 12 Number of Dresses: 8 The Total order is: 80.951625 Amount Tended? 100 ==================================== -/- Georgetown Cleaning Services -/==================================== Customer: Gretchen McCormack Home Phone: (410) 739-2884 Date & Time: 4/9/2001 10:25:00 AM -----------------------------------Item Type Qty Unit/Price Sub-Total
98 -----------------------------------Shirts 5 $0.95 $4.75 Pants 12 $2.95 $35.40 Dresses 8 $4.55 $36.40 -----------------------------------Total Order: $76.55 Tax Rate: 5.75 % Tax Amount: $4.40 Net Price: 80.95 -----------------------------------Amount Tended: $100.00 Difference: $19.05 ==================================== 3. Return to Notepad
Line Formatting In the above programs, to display a line of text, we easily used Write() or WriteLine(). To position text of different lengths one above the other, we had to "corrupt" a string by including extra-empty spaces. Such a technique is uncertain and less professional. Fortunately, you can highly format how a string or a line of text should display. The .NET Framework provides mechanisms to control the amount of space used to display a string of text and how to align that string on its line. To specify the amount of space used to display a string, you can use its placeholder in Write() or WriteLine(). To do this, in the placeholder, type the 0 or the incrementing number of the placer and its formatting character if necessary and if any. Then, type a comma followed by the number of characters equivalent to the desired width. Here are examples: using System; // An Exercise class class Exercise { static void Main() { String FullName = "Anselme Bogos"; int Age = 15; double HSalary = 22.74; Console.WriteLine("Full Name: {0,20}", FullName); Console.WriteLine("Age:{0,14}", Age.ToString()); Console.WriteLine("Distance: {0:C,8}", HSalary.ToString()); }
Console.WriteLine();
} This would produce: Full Name: Anselme Bogos Age: 15 Distance: 22.74 The sign you provide for the width is very important. If it is positive, the line of text is aligned to the right. This should be your preferred alignment for numeric values. If the number is
99
negative, then the text is aligned to the left.
Data and Time Formatting As mentioned earlier, when the user enters a date value for a DateTime variable, the compiler adds a time part to the value. Fortunately, if you want to consider only the date or only the time part, you can specify this to the compiler. To support this, the DateTime data type provides a series of letters you can use to format how its value should be displayed to the user. The character is entered in the placeholder of the DateTime variable after the 0 or the incremental numeric value.
Practical Learning: Controlling Date/Time Formatting 1. To control formatting of date and time, change the file as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { static void Main() { // Price of items const decimal PriceOneShirt const decimal PriceAPairOfPants const decimal PriceOneDress const decimal TaxRate
= = = =
0.95M; 2.95M; 4.55M; 0.0575M;
// 5.75%
// Basic information about an order string CustomerName, HomePhone; DateTime OrderDate, OrderTime; // Unsigned numbers to represent cleaning items uint NumberOfShirts, NumberOfPants, NumberOfDresses; // Each of these sub totals will be used for cleaning items decimal SubTotalShirts, SubTotalPants, SubTotalDresses; // Values used to process an order decimal TotalOrder, TaxAmount, SalesTotal; decimal AmountTended, Difference; Console.WriteLine("-/- Georgetown Cleaning Services -/-"); // Request order information from the user Console.Write("Enter Customer Name: "); CustomerName = Console.ReadLine(); Console.Write("Enter Customer Phone: "); HomePhone = Console.ReadLine(); Console.Write("Enter the order date(mm/dd/yyyy): "); OrderDate = DateTime.Parse(Console.ReadLine()); Console.Write("Enter the order time(hh:mm AM/PM): "); OrderTime = DateTime.Parse(Console.ReadLine()); // Request the quantity of each category of items Console.Write("Number of Shirts: "); NumberOfShirts = uint.Parse(Console.ReadLine());
100
Console.Write("Number of Pants: "); NumberOfPants = uint.Parse(Console.ReadLine()); Console.Write("Number of Dresses: "); NumberOfDresses = uint.Parse(Console.ReadLine()); // Perform the necessary calculations SubTotalShirts = NumberOfShirts * PriceOneShirt; SubTotalPants = NumberOfPants * PriceAPairOfPants; SubTotalDresses = NumberOfDresses * PriceOneDress; // Calculate the "temporary" total of the order TotalOrder = SubTotalShirts + SubTotalPants + SubTotalDresses; // Calculate the tax amount using a constant rate TaxAmount = TotalOrder * TaxRate; // Add the tax amount to the total order SalesTotal = TotalOrder + TaxAmount;
SalesTotal);
// Communicate the total to the user... Console.WriteLine("\nThe Total order is: {0:C}", // and request money for the order Console.Write("Amount Tended? "); AmountTended = decimal.Parse(Console.ReadLine()); // Calculate the difference owed to the customer // or that the customer still owes to the store Difference = AmountTended - SalesTotal; Console.WriteLine(); // Display the receipt Console.WriteLine("===================================="); Console.WriteLine("-/- Georgetown Cleaning Services -/-"); Console.WriteLine("===================================="); Console.WriteLine("Customer: {0}", CustomerName); Console.WriteLine("Home Phone: {0}", HomePhone); Console.WriteLine("Order Date: {0:D}", OrderDate); Console.WriteLine("Order Time: {0:t}", OrderTime); Console.WriteLine("------------------------------------"); Console.WriteLine("Item Type Qty Unit/Price Sub-Total"); Console.WriteLine("------------------------------------"); Console.WriteLine("Shirts {0} {1} {2}", NumberOfShirts.ToString(), PriceOneShirt.ToString("C"), SubTotalShirts.ToString("C")); Console.WriteLine("Pants {0} {1} {2}", NumberOfPants.ToString(), PriceAPairOfPants.ToString("C"), SubTotalPants.ToString("C")); Console.WriteLine("Dresses {0} {1} {2}", NumberOfDresses.ToString(), PriceOneDress.ToString("C"), SubTotalDresses.ToString("C")); Console.WriteLine("------------------------------------");
101 Console.WriteLine("Total Order: {0}", TotalOrder.ToString("C")); Console.WriteLine("Tax Rate: {0}", TaxRate.ToString("P")); Console.WriteLine("Tax Amount: {0}", TaxAmount.ToString("C")); Console.WriteLine("Net Price: {0}", SalesTotal.ToString("C")); Console.WriteLine("------------------------------------"); Console.WriteLine("Amount Tended: {0}", AmountTended.ToString("C")); Console.WriteLine("Difference: {0}", Difference.ToString("C")); Console.WriteLine("===================================="); } } } 2. Save, compile, and run the program. Here is an example: -/- Georgetown Cleaning Services -/Enter Customer Name: Antoinette Calhoun Enter Customer Phone: (703) 797-1135 Enter the order date(mm/dd/yyyy): 04/12/2002 Enter the order time(hh:mm AM/PM): 2:12 PM Number of Shirts: 5 Number of Pants: 2 Number of Dresses: 1 The Total order is: $16.07 Amount Tended? 20 ==================================== -/- Georgetown Cleaning Services -/==================================== Customer: Antoinette Calhoun Home Phone: (703) 797-1135 Order Date: Friday, April 12, 2002 Order Time: 2:12 PM -----------------------------------Item Type Qty Unit/Price Sub-Total -----------------------------------Shirts 5 $0.95 $4.75 Pants 2 $2.95 $5.90 Dresses 1 $4.55 $4.55 -----------------------------------Total Order: $15.20 Tax Rate: 5.75 % Tax Amount: $0.87 Net Price: $16.07 -----------------------------------Amount Tended: $20.00 Difference: $3.93 ==================================== 3. Type Exit and close Notepad
102
Introduction to Conditions Overview of Conditions Introduction A program is a series of instructions that ask the computer (actually the compiler) to check some situations and to act accordingly. To check such situations, the computer spends a great deal of its time performing comparisons between values. A comparison is a Boolean operation that produces a true or a false result, depending on the values on which the comparison is performed. A comparison is performed between two values of the same type; for example, you can compare two numbers, two characters, or the names of two cities. On the other hand, a comparison between two disparate value doesn't bear any meaning. For example, it is difficult to compare a telephone number and somebody's age, or a music category and the distance between two
103
points. Like the binary arithmetic operations, the comparison operations are performed on two values. Unlike arithmetic operations where results are varied, a comparison produces only one of two results. The result can be a logical true or false. When a comparison is true, it has an integral value of 1 or positive; that is, a value greater than 0. If the comparison is not true, it is considered false and carries an integral value of 0. The C# language is equipped with various operators used to perform any type of comparison between similar values. The values could be numeric, strings, or objects (operations on objects are customized in a process referred to as Operator Overloading).
Introduction There are primary assumptions you should make when writing statements used in conditions: •
Simplicity and Clarity: A statement should be clear enough and possibly simple but as complete as possible. When a statement becomes long, it can lead to being segmented in short parts, which deceives its clarity and may create other issues.
•
Factual: The statement must be presented as fact and not as opinion. This means that you don't have to like the statement but the majority, including you, must agree that it is true. In fact, the statement doesn't have to be correct but it must be agreed upon to be true. Based on this, a statement such as "An hour contains 45 minutes" doesn't have to fit your way of thinking but it must be considered as true or as false. A statement such as "This job applicant is attractive" is an opinion and therefore must not be considered in a conditional statement.
•
Circumstantial Truthfulness: At the time the statement is made, it must be considered as true even if it can change at another time. For example, supposed that, in a certain year, a statement is formulated as "This year, the month of February has 28 days". Although allowed, you should refrain from regularly using circumstantial truthfulness, unless you have to.
•
Inverse: A statement must be able to find its reverse. This means that, when a statement is made and decided upon to be true or false, an inverse statement must be found to make it false or true. For example, if you have a statement such as "This job applicant is 18 years old", you must be able to state that "This job applicant is not 18 years old" or "This job applicant is younger than 18".
In your programs, make sure you clearly formulate your statements. This would make your programs easy to read and troubleshoot when problems occur.
Logical Operations The Equality Operator == To compare two variables for equality, C# uses the == operator. Its syntax is: Value1 == Value2 The equality operation is used to find out whether two variables (or one variable and a constant) hold the same value. From our syntax, the compiler would compare the value of
104
Value1 with that of Value2. If Value1 and Value2 hold the same value, the comparison produces a true result. If they are different, the comparison renders false.
Most of the comparisons performed in C# will be applied to conditional statements. The result of a comparison can also be assigned to a variable. To store the result of a comparison, you should include the comparison operation between parentheses. Here is an example: using System; class NewProject { static void Main() { int Value1 = 15; int Value2 = 24; Console.Write("Value 1 = "); Console.WriteLine(Value1); Console.Write("Value 2 = "); Console.WriteLine(Value2); Console.Write("Comparison of Value1 == 15 produces "); Console.WriteLine(Value1 == 15); }
} This would produce:
Value 1 = 15 Value 2 = 24 Comparison of Value1 == 15 produces True It is important to make a distinction between the assignment "=" and the logical equality operator "==". The first is used to give a new value to a variable, as in Number = 244. The operand on the left side of = must always be a variable and never a constant. The == operator is never used to assign a value; this would cause an error. The == operator is used only to compare to values. The operands on both sides of == can be variables, constants, or one can be a variable while the other is a constant. If you use one operator in place of the other, you
105
would receive an error when you compile the program.
The Logical Not Operator ! When a variable is declared and receives a value (this could be done through initialization or a change of value) in a program, it becomes alive. It can then participate in any necessary operation. The compiler keeps track of every variable that exists in the program being processed. When a variable is not being used or is not available for processing (in visual programming, it would be considered as disabled) to make a variable (temporarily) unusable, you can nullify its value. C# considers that a variable whose value is null is stern. To render a variable unavailable during the evolution of a program, apply the logical not operator which is !. Its syntax is: !Value There are two main ways you can use the logical not operator. As we will learn when studying conditional statements, the most classic way of using the logical not operator is to check the state of a variable. To nullify a variable, you can write the exclamation point to its left. When used like that, you can display its value using the cout extractor. You can even assign it to another variable. Here is an example: using System; class NewProject { static void Main() { bool HasAirCondition = true; bool DoesIt; Console.Write("HasAirCondition = "); Console.WriteLine(HasAirCondition); DoesIt = !HasAirCondition; Console.Write("DoesIt = "); Console.WriteLine(DoesIt); }
} This would produce:
HasAirCondition = True DoesIt = False When a variable holds a value, it is "alive". To make it not available, you can "not" it. When a variable has been "notted", its logical value has changed. If the logical value was true, which is 1, it would be changed to false, which is 0. Therefore, you can inverse the logical value of a variable by "notting" or not "notting" it.
The Inequality Operator != As opposed to Equality, C# provides another operator used to compare two values for
106
inequality. This operation uses a combination of equality and logical not operators. It combines the logical not ! and a simplified == to produce !=. Its syntax is: Value1 != Value2 The != is a binary operator (like all logical operator except the logical not, which is a unary operator) that is used to compare two values. The values can come from two variables as in Variable1 != Variable2. Upon comparing the values, if both variables hold different values, the comparison produces a true or positive value. Otherwise, the comparison renders false or a null value.
Here is an example: using System; class NewProject { static void Main() { int Value1 = 212; int Value2 = -46; bool Value3 = (Value1 != Value2);
}
Console.Write("Value1 = "); Console.WriteLine(Value1); Console.Write("Value2 = "); Console.WriteLine(Value2); Console.Write("Value3 = "); Console.Write(Value3); Console.WriteLine();
} The inequality is obviously the opposite of the equality.
The Comparison for a Lower Value <
107
To find out whether one value is lower than another, use the < operator. Its syntax is: Value1 < Value2 The value held by Value1 is compared to that of Value2. As it would be done with other operations, the comparison can be made between two variables, as in Variable1 < Variable2. If the value held by Variable1 is lower than that of Variable2, the comparison produces a true or positive result.
Here is an example: using System; class NewProject { static void Main() { int Value1 = 15; bool Value2 = (Value1 < 24);
}
Console.Write("Value 1 = "); Console.WriteLine(Value1); Console.Write("Value 2 = "); Console.WriteLine(Value2); Console.WriteLine();
} This would produce: Value 1 = 15 Value 2 = True
Combining Equality and Lower Value <= The previous two operations can be combined to compare two values. This allows you to know if two values are the same or if the first is less than the second. The operator used is <= and
108
its syntax is: Value1 <= Value2 The <= operation performs a comparison as any of the last two. If both Value1 and VBalue2 hold the same value, result is true or positive. If the left operand, in this case Value1, holds a value lower than the second operand, in this case Value2, the result is still true.
Here is an example: using System; class NewProject { static void Main() { int Value1 = 15; bool Value2 = (Value1 <= 24);
}
Console.Write("Value 1 = "); Console.WriteLine(Value1); Console.Write("Value 2 = "); Console.WriteLine(Value2); Console.WriteLine();
} This would produce: Value 1 = 15 Value 2 = True
The Comparison for a Greater Value > When two values of the same type are distinct, one of them is usually higher than the other. C# provides a logical operator that allows you to find out if one of two values is greater than the other. The operator used for this operation uses the > symbol. Its syntax is: Value1 > Value2
109
Both operands, in this case Value1 and Value2, can be variables or the left operand can be a variable while the right operand is a constant. If the value on the left of the > operator is greater than the value on the right side or a constant, the comparison produces a true or positive value . Otherwise, the comparison renders false or null.
The Greater Than or Equal Operator >= The greater than or the equality operators can be combined to produce an operator as follows: >=. This is the "greater than or equal to" operator. Its syntax is: Value1 >= Value2 A comparison is performed on both operands: Value1 and Value2. If the value of Value1 and that of Value2 are the same, the comparison produces a true or positive value. If the value of the left operand is greater than that of the right operand,, the comparison produces true or positive also. If the value of the left operand is strictly less than the value of the right operand, the comparison produces a false or null result.
110
Here is a summary table of the logical operators we have studied: Operator Meaning Example Opposite == Equality to a == b != != Not equal to 12 != 7 == < Less than 25 < 84 >= <= Less than or equal to Cab <= Tab > > Greater than 248 > 55 <= Greater than or equal >= Val1 >= Val2 < to
Conditional Statements Introduction to Conditional Statements Introduction Imagine you are writing a program for the Motor Vehicle Administration. When processing a driver's license, you want to be able to ask an applicant if he or she wants to be an organ donor. This section of the program can appear as follows: using System; class Exercise { static void Main() {
111 string Answer; Console.Write("Are you willing to be an organ donor? "); Answer = Console.ReadLine(); return 0; }
} The possible answers to this question are y, yes, Y, Yes, YES, n, N, no, No, NO, I don’t know, It depends, Why are you asking?, What do you mean?, What kind of organ are you referring to? What kind of person would possibly want my organ? Are you planning to sell my body parts?, etc. When you ask this type of question, make sure you let the applicant know that this is a simple question expecting a simple answer. For example, the above question can be formulated as follows:
using System; class Exercise { static void Main() { string Answer; Console.Write("Are you willing to be an organ donor (y=Yes/n=No)? "); Answer = Console.ReadLine(); }
return 0;
} This time, the applicant knows that the expected answers are simply y for Yes or n for No.
Practical Learning: Introducing Conditional Statements 1. Start Microsoft Visual C# or Visual Studio .NET 2. On the main menu, click File -> New -> Project 3. If necessary, in the Project Types list of the New Project dialog box, click Visual C# Projects 4. In the Templates list, click Empty Project
5. In the Name text box, replace the name with MVD1 and specify the desired path in the Location 6. Click OK 7. To create a source file for the project, on the main menu, click Project -> Add New Item... 8. In the Add New Item dialog box, in the Templates list, click Code File
9. In the Name text box, delete the suggested name and replace it with Exercise 10. Click Open 11. In the empty file, type the following: using System;
112 namespace MotorVehicleDivision { class Exercise { static void Main() { string FirstName, LastName; Console.WriteLine(" -=- Motor Vehicle Administration -=-");
Console.WriteLine(" --- Driver's License Application
---");
Console.Write("First Name: "); FirstName = Console.ReadLine(); Console.Write("Last Name: "); LastName = Console.ReadLine(); Console.WriteLine("\n -=- Motor Vehicle Administration
-=-");
Console.WriteLine(" --- Driver's License Information
---");
Console.WriteLine("Full Name: {0} {1}\n", FirstName,
LastName); }
}
} 12. To execute the application, on the main menu, click Debug -> Start Without Debugging 13. Return to Visual C#
Boolean Variables A variable is referred to as Boolean if it is meant to carry only one of two logical values stated as true or false. For this reason, such a variable is used only when testing conditions or when dealing with conditional statements. To declare a Boolean variable, you can use the bool keyword. Here is an example of declaring a Boolean variable: bool TheStudentIsHungry; After declaring a Boolean variable, you can give it a value by assigning it a true or false value. Here is an example: using System; class ObjectName { static void Main() { bool TheStudentIsHungry; TheStudentIsHungry = true; Console.Write("The Student Is Hungry expression is: "); Console.WriteLine(TheStudentIsHungry); TheStudentIsHungry = false; Console.Write("The Student Is Hungry expression is: ");
113 Console.WriteLine(TheStudentIsHungry);
} }
This would produce: The Student Is Hungry expression is: True The Student Is Hungry expression is: False You can also give its first value to a variable when declaring it. In this case, the above variable can be declared and initialized as follows: bool TheStudentIsHungry = true;
Practical Learning: Using a Boolean Variable 1. To use an example of a Boolean variable, change the file as follows: using System; namespace MotorVehicleDivision { class Exercise { static void Main() { string FirstName, LastName; bool WillingToBeAnOrganDonor; Console.WriteLine(" -=- Motor Vehicle Administration -=-");
Console.WriteLine(" --- Driver's License Application
---");
Console.Write("First Name: "); FirstName = Console.ReadLine(); Console.Write("Last Name: "); LastName = Console.ReadLine(); Console.Write("Are you willing to be an Organ Donor(True=Yes/False=No)? "); WillingToBeAnOrganDonor = bool.Parse(Console.ReadLine()); Console.WriteLine("\n -=- Motor Vehicle Administration -=-");
Console.WriteLine(" --- Driver's License Information
---");
Console.WriteLine("Full Name: {0} {1}", FirstName,
LastName);
Console.WriteLine("Organ Donor? {0}", WillingToBeAnOrganDonor); } }
return 0;
}
2. Execute the application. Here is an example:
114 -=- Motor Vehicle Administration -=--- Driver's License Application --First Name: Ahmed Last Name: Kouakou Are you willing to be an Organ Donor(True=Yes/False=No)? True -=- Motor Vehicle Administration -=--- Driver's License Information --Full Name: Ahmed Kouakou Organ Donor? True 3. Return to Visual C#
Formulations of Conditional Statements if a Condition is True One of the most regularly performed operations on a program consists of checking that a condition is true or false. When something is true, you may act one way. If it is false, you act another way. A condition that a program checks must be clearly formulated in a statement, following specific rules. The statement can come from you or from the computer itself. Examples of statements are: •
"You are 12 years old"
•
"It is raining outside"
•
You live in Sydney"
One of the comparisons the computer performs is to find out if a statement is true (in reality, programmers (like you) write these statements and the computer only follows your logic). If a statement is true, the computer acts on a subsequent instruction. The comparison using the if statement is used to check whether a condition is true or false. The syntax to use it is: if(Condition) Statement; If the Condition is true, then the compiler would execute the Statement. The compiler ignores anything else:
115
If the statement to execute is (very) short, you can write it on the same line with the condition that is being checked. Consider a program that is asking a user to answer Yes or No to a question such as "Are you ready to provide your credit card number?". A source file of such a program could look like this: using System; class NewProject { static void Main() { char Answer; string Ans;
");
// Request the availability of a credit card from the user Console.Write("Are you ready to provide your credit card number(1=Yes/0=No)? Ans = Console.ReadLine(); Answer = char.Parse(Ans);
// Since the user is ready, let's process the credit card transaction if(Answer == '1') Console.WriteLine("\nNow we will get your credit card information."); } } You can write the if condition and the statement on different lines; this makes your program easier to read. The above code could be written as follows: using System; class NewProject { static void Main() { char Answer; string Ans; // Request the availability of a credit card from the user Console.Write("Are you ready to provide your credit card number(1=Yes/0=No)? "); Ans = Console.ReadLine(); Answer = char.Parse(Ans); transaction
// Since the user is ready, let's process the credit card if(Answer == '1') Console.WriteLine("\nNow we will get your credit card
information."); }
} You can also write the statement on its own line if the statement is too long to fit on the same
116
line with the condition. Although the (simple) if statement is used to check one condition, it can lead to executing multiple dependent statements. If that is the case, enclose the group of statements between an opening curly bracket “{“ and a closing curly bracket “}”. Here is an example: using System; class NewProject { static void Main() { char Answer; string Ans, CreditCardNumber; // Request the availability of a credit card from the user Console.Write("Are you ready to provide your credit card number(1=Yes/0=No)? "); Ans = Console.ReadLine(); Answer = char.Parse(Ans); transaction
information.");
// Since the user is ready, let's process the credit card if(Answer == '1') { Console.WriteLine("Now we will get your credit card Console.Write("Please enter your credit card number without
spaces: "); } }
CreditCardNumber = Console.ReadLine();
} If you omit the brackets, only the statement that immediately follows the condition would be executed.
Practical Learning: Using if 1. To state an if condition, change the program as follows: using System; namespace MotorVehicleDivision { class Exercise { static void Main() { string FirstName, LastName; string OrganDonorAnswer; -=-");
Console.WriteLine(" -=- Motor Vehicle Administration
117 Console.WriteLine(" --- Driver's License Application ---");
Console.Write("First Name: "); FirstName = Console.ReadLine(); Console.Write("Last Name: "); LastName = Console.ReadLine(); Console.Write("Are you willing to be an Organ
Donor(1=Yes/0=No)? ");
OrganDonorAnswer = Console.ReadLine(); Console.WriteLine("\n -=- Motor Vehicle Administration
-=-");
Console.WriteLine(" --- Driver's License Information
---");
Console.WriteLine("Full Name:
LastName); } }
{0} {1}", FirstName,
Console.Write("Organ Donor? "); if( OrganDonorAnswer == "1" ) Console.WriteLine("Yes");
}
2. Execute the application. Here is an example: -=- Motor Vehicle Administration -=--- Driver's License Application --First Name: Catherine Last Name: Wallington Are you willing to be an Organ Donor(1=Yes/0=No)? 1 -=- Motor Vehicle Administration -=--- Driver's License Information --Full Name: Catherine Wallington Organ Donor? Yes 3. Return to Visual C#
Otherwise: if…else The if condition is used to check one possibility and ignore anything else. Usually, other conditions should be considered. In this case, you can use more than one if statement. For example, on a program that asks a user to answer Yes or No, although the positive answer is the most expected, it is important to offer an alternate statement in case the user provides another answer. Here is an example: using System; class NewProject { static void Main() { char Answer; string Ans; // Request the availability of a credit card from the user Console.Write("Do you consider yourself a hot-tempered
118 individual(y=Yes/n=No)? "); Ans = Console.ReadLine(); Answer = char.Parse(Ans); if( Answer == 'y' ) // First Condition { Console.WriteLine("\nThis job involves a high level of selfcontrol.");
}
Console.WriteLine("We will get back to you.\n"); } if( Answer == 'n' ) // Second Condition Console.Write("\nYou are hired!\n");
} Here is an example of running the program: Do you consider yourself a hot-tempered individual(y=Yes/n=No)? y This job involves a high level of self-control. We will get back to you. Press any key to continue The problem with the above program is that the second if is not an alternative to the first, it is just another condition that the program has to check and execute after executing the first. On that program, if the user provides y as the answer to the question, the compiler would execute the content of its statement and the compiler would execute the second if condition. You can also ask the compiler to check a condition; if that condition is true, the compiler will execute the intended statement. Otherwise, the compiler would execute alternate statement. This is performed using the syntax: if(Condition) Statement1; else Statement2;
The above program would better be written as: using System; class NewProject
119 { static void Main() { char Answer; string Ans; // Request the availability of a credit card from the user Console.Write("Do you consider yourself a hot-tempered individual(y=Yes/n=No)? "); Ans = Console.ReadLine(); Answer = char.Parse(Ans); if( Answer == 'y' ) // First Condition { Console.WriteLine("\nThis job involves a high level of selfcontrol.");
}
Console.WriteLine("We will get back to you.\n"); } else // Second Condition Console.Write("\nYou are hired!\n");
}
Practical Learning: Using if...else 1. Make the following changes to the file: using System; namespace MotorVehicleDivision { class Exercise { static void Main() { string FirstName, LastName; string OrganDonorAnswer; char Gender; -=-"); ---");
Donor(1=Yes/0=No)? ");
Console.WriteLine(" -=- Motor Vehicle Administration Console.WriteLine(" --- Driver's License Application Console.Write("First Name: "); FirstName = Console.ReadLine(); Console.Write("Last Name: "); LastName = Console.ReadLine(); Console.Write("Gender(F=Female/M=Male): "); Gender = char.Parse(Console.ReadLine()); Console.Write("Are you willing to be an Organ OrganDonorAnswer = Console.ReadLine();
120 Console.WriteLine("\n -=- Motor Vehicle Administration -=-");
Console.WriteLine(" --- Driver's License Information
---");
Console.WriteLine("Full Name:
LastName);
} }
{0} {1}", FirstName,
Console.WriteLine("Gender: {0}", Gender); Console.Write("Organ Donor? "); if( OrganDonorAnswer == "1" ) Console.WriteLine("Yes"); else if( OrganDonorAnswer == "0" ) Console.WriteLine("No");
}
2. Execute the application and test it twice, once with 1 to the question, then with 0 to the last question 3. Return to Visual C#
The Ternary Operator (?:) The conditional operator behaves like a simple if…else statement. Its syntax is: Condition ? Statement1 : Statement2; The compiler would first test the Condition. If the Condition is true, then it would execute Statement1, otherwise it would execute Statement2. When you request two numbers from the user and would like to compare them, the following program would do find out which one of both numbers is higher. The comparison is performed using the conditional operator: using System; class NewProject { static void Main() { int Number1, Number2, Maximum; string Num1, Num2; Console.Write("Enter first numbers: "); Num1 = Console.ReadLine(); Console.Write("Enter second numbers: "); Num2 = Console.ReadLine(); Number1 = int.Parse(Num1); Number2 = int.Parse(Num2); Maximum = (Number1 < Number2) ? Number2 : Number1; Console.Write("\nThe maximum of "); Console.Write(Number1); Console.Write(" and "); Console.Write(Number2); Console.Write(" is "); Console.WriteLine(Maximum);
121
}
Console.WriteLine();
} Here is an example of running the program: Enter first numbers: 244 Enter second numbers: 68 The maximum of 244 and 68 is 244
Practical Learning: Using the Ternary Operator
Formulating Expressions Counting and Looping While a Statement is True The C# language provides a set of control statements that allows you to conditionally control data input and output. These controls are referred to as loops. The while statement examines or evaluates a condition. The syntax of the while statement is: while(Condition) Statement;
122
To execute this expression, the compiler first examines the Condition. If the Condition is true, then it executes the Statement. After executing the Statement, the Condition is checked again. AS LONG AS the Condition is true, it will keep executing the Statement. When or once the Condition becomes false, it exits the loop. Here is an example: int Number; while( Number <= 12 ) { Console.Write("Number "); Console.WriteLine(Number); Number++; } To effectively execute a while condition, you should make sure you provide a mechanism for the compiler to use a get a reference value for the condition, variable, or expression being checked. This is sometimes in the form of a variable being initialized although it could be some other expression. Such a while condition could be illustrated as follows:
123
An example would be: using System; class NewProject { static void Main() { int Number = 0; while( Number <= 12 ) { Console.Write("Number "); Console.WriteLine(Number); Number++; } Console.WriteLine(); }
}
This would produce: Number Number Number Number Number Number Number Number Number Number
0 1 2 3 4 5 6 7 8 9
124 Number 10 Number 11 Number 12 Press any key to continue
Practical Learning: Introducing Conditional Statements 1. Start Microsoft Visual C# or Visual Studio .NET 2. On the main menu, click File -> New -> Project 3. If necessary, in the Project Types list of the New Project dialog box, click Visual C# Projects 4. In the Templates list, click Empty Project
5. In the Name text box, replace the name with DeptStore1 and specify the desired path in the Location
6. Click OK 7. To create a source file for the project, on the main menu, click Project -> Add New Item... 8. In the Add New Item dialog box, in the Templates list, click Code File
9. In the Name text box, delete the suggested name and replace it with Exercise 10. Click Open 11. In the empty file, type the following: using System; enum TypeOfApplication { NewDriversLicense = 1, UpgradeFromIDCard, TransferFromAnotherState }; class Exercise { static void Main() { TypeOfApplication AppType; string FirstName, LastName; string OrganDonorAnswer; char Sex; string Gender; char DLClass; Console.WriteLine(" -=- Motor Vehicle Administration -=-"); Console.WriteLine(" --- Driver's License Application ---"); Console.WriteLine(" - Select the type of application -"); Console.WriteLine("1 - Applying for a brand new Driver's License"); Console.WriteLine("2 - Applicant already had an ID Card and is applying for a Driver's License");
125 Console.WriteLine("3 - Applicant is transferring his/her Driver's License from another state"); Console.Write("Your Choice: "); int type = int.Parse(Console.ReadLine()); Console.Write("First Name: "); FirstName = Console.ReadLine(); Console.Write("Last Name: "); LastName = Console.ReadLine(); Console.Write("Sex(F=Female/M=Male): "); Sex = char.Parse(Console.ReadLine()); Console.WriteLine(" - Driver's License Class -"); Console.WriteLine("A - All Non-commercial vehicles except motorcycles"); Console.WriteLine("B - Non-commercial vehicles up to and including 26,001/more lbs."); Console.WriteLine("C - Cars, pick-up trucks, non-commercial vehicles 26,000 lbs."); Console.WriteLine("K - Mopeds"); Console.WriteLine("M - Motorcycles"); Console.Write("Your Choice: "); DLClass = char.Parse(Console.ReadLine()); ");
Console.Write("Are you willing to be an Organ Donor(1=Yes/0=No)? OrganDonorAnswer = Console.ReadLine(); if( Sex == 'f' ) Gender = "Female"; else if( Sex == 'F' ) Gender = "Female"; else if( Sex == 'm' ) Gender = "Male"; else if( Sex == 'M' ) Gender = "Male"; else Gender = "Unknown"; Console.WriteLine("\n -=- Motor Vehicle Administration -=-"); Console.WriteLine(" --- Driver's License Information ---"); AppType = (TypeOfApplication)type; Console.Write("Type of Application: "); switch(AppType) { case TypeOfApplication.NewDriversLicense: Console.WriteLine("New Driver's License"); break; case TypeOfApplication.UpgradeFromIDCard: Console.WriteLine("Upgrade From Identity Card"); break; case TypeOfApplication.TransferFromAnotherState: Console.WriteLine("Transfer From Another State"); break;
126 default: Console.WriteLine("Not Specified"); break; } Console.WriteLine("Full Name: Console.WriteLine("Sex: switch(DLClass) { case 'a': case 'A': Console.WriteLine("Class: break; case 'b': case 'B': Console.WriteLine("Class: break; case 'c': case 'C': Console.WriteLine("Class: break; case 'k': case 'K': Console.WriteLine("Class: break; case 'm': case 'M': Console.WriteLine("Class: break; default: Console.WriteLine("Class: break; }
{0} {1}", FirstName, LastName); {0}", Gender);
A");
B");
C");
K");
M"); Unknown");
Console.Write("Organ Donor? "); Console.WriteLine(OrganDonorAnswer == "1" ? "Yes" : (OrganDonorAnswer == "0" ? "No" : "Invalid Answer")); }
return 0;
} 12. To execute the application, on the main menu, click Debug -> Start Without Debugging. Here is an example: -=- Motor Vehicle Administration -=--- Driver's License Application --- Select the type of application 1 - Applying for a brand new Driver's License 2 - Applicant already had an ID Card and is applying for a Driver's License 3 - Applicant is transferring his/her Driver's License from another state Your Choice: 6 First Name: Henry
127 Last Name: Dricks Sex(F=Female/M=Male): P - Driver's License Class A - All Non-commercial vehicles except motorcycles B - Non-commercial vehicles up to and including 26,001/more lbs. C - Cars, pick-up trucks, non-commercial vehicles 26,000 lbs. K - Mopeds M - Motorcycles Your Choice: G Are you willing to be an Organ Donor(1=Yes/0=No)? 4 -=- Motor Vehicle Administration -=--- Driver's License Information --Type of Application: Not Specified Full Name: Henry Dricks Sex: Unknown Class: Unknown Organ Donor? Invalid Answer 13. After using it, Return to Visual C#
The do...while Statement The do…while statement uses the following syntax: do Statement while (Condition);
The do…while condition executes a Statement first. After the first execution of the Statement, it examines the Condition. If the Condition is true, then it executes the Statement again. It will keep executing the Statement AS LONG AS the Condition is true. Once the Condition becomes false, the looping (the execution of the Statement) would stop. If the Statement is a short one, such as made of one line, simply write it after the do keyword. Like the if and the while statements, the Condition being checked must be included between parentheses. The whole do…while statement must end with a semicolon.
128
Another version of the counting program seen previously would be: using System; class NewProject { static void Main() { int Number = 0; do {
Console.Write("Number "); Console.WriteLine(Number); Number++; }while( Number <= 12 ); }
Console.WriteLine();
} If the Statement is long and should span more than one line, start it with an opening curly bracket and end it with a closing curly bracket. The do…while statement can be used to insist on getting a specific value from the user. For example, since our ergonomic program would like the user to sit down for the subsequent exercise, you can modify your program to continue only once she is sitting down. Here is an example on how you would accomplish that: using System; class NewProject { static void Main() { char SittingDown; string SitDown; Console.Write("For the next exercise, you need to be sitting down\n"); do { Console.Write("Are you sitting down now(y/n)? "); SitDown = Console.ReadLine(); SittingDown = char.Parse(SitDown); } while( !(SittingDown == 'y') ); Console.WriteLine(); }
}
Here is an example of running the program: For Are Are Are Are
the you you you you
next exercise, you need to be sitting down sitting down now(y/n)? t sitting down now(y/n)? h sitting down now(y/n)? G sitting down now(y/n)? y
129
Practical Learning: Using do...While 1. Change the file as follows: using System; enum TypeOfApplication { NewDriversLicense = 1, UpgradeFromIDCard, TransferFromAnotherState }; class Exercise { static void Main() { TypeOfApplication AppType; int type; string FirstName, LastName; string OrganDonorAnswer; char Sex; string Gender; char DLClass; Console.WriteLine(" -=- Motor Vehicle Administration -=-"); Console.WriteLine(" --- Driver's License Application ---"); do {
Console.WriteLine(" - Select the type of application -"); Console.WriteLine("1 - Applying for a brand new Driver's License"); Console.WriteLine("2 - Applicant already had an ID Card and is applying for a Driver's License"); Console.WriteLine("3 - Applicant is transferring his/her Driver's License from another state"); Console.Write("Your Choice: "); type = int.Parse(Console.ReadLine()); Console.WriteLine(""); } while(type > 3); Console.Write("First Name: "); FirstName = Console.ReadLine(); Console.Write("Last Name: "); LastName = Console.ReadLine(); Console.Write("\nSex(F=Female/M=Male): "); Sex = char.Parse(Console.ReadLine()); Console.WriteLine("\n - Driver's License Class -"); Console.WriteLine("A - All Non-commercial vehicles except motorcycles"); Console.WriteLine("B - Non-commercial vehicles up to and including 26,001/more lbs."); Console.WriteLine("C - Cars, pick-up trucks, non-commercial vehicles 26,000 lbs."); Console.WriteLine("K - Mopeds"); Console.WriteLine("M - Motorcycles"); Console.Write("Your Choice: "); DLClass = char.Parse(Console.ReadLine());
130
Console.Write("\nAre you willing to be an Organ Donor(1=Yes/0=No)? "); OrganDonorAnswer = Console.ReadLine(); if( Sex == 'f' ) Gender = "Female"; else if( Sex == 'F' ) Gender = "Female"; else if( Sex == 'm' ) Gender = "Male"; else if( Sex == 'M' ) Gender = "Male"; else Gender = "Unknown"; Console.WriteLine("\n -=- Motor Vehicle Administration -=-"); Console.WriteLine(" --- Driver's License Information ---"); AppType = (TypeOfApplication)type; Console.Write("Type of Application: "); switch(AppType) { case TypeOfApplication.NewDriversLicense: Console.WriteLine("New Driver's License"); break; case TypeOfApplication.UpgradeFromIDCard: Console.WriteLine("Upgrade From Identity Card"); break; case TypeOfApplication.TransferFromAnotherState: Console.WriteLine("Transfer From Another State"); break; default: Console.WriteLine("Not Specified"); break; } Console.WriteLine("Full Name: {0} {1}", FirstName, LastName); Console.WriteLine("Sex: {0}", Gender); switch(DLClass) { case 'a': case 'A': Console.WriteLine("Class: break; case 'b': case 'B': Console.WriteLine("Class: break; case 'c': case 'C': Console.WriteLine("Class: break; case 'k': case 'K': Console.WriteLine("Class:
A");
B");
C");
K");
131 break; case 'm': case 'M': Console.WriteLine("Class: break; default: Console.WriteLine("Class: break; }
M"); Unknown");
Console.Write("Organ Donor? "); Console.WriteLine(OrganDonorAnswer == "1" ? "Yes" : (OrganDonorAnswer == "0" ? "No" : "Invalid Answer")); return 0; }
}
2. Save, compile, and test it. Here is an example: -=- Motor Vehicle Administration -=--- Driver's License Application --- Select the type of application 1 - Applying for a brand new Driver's License 2 - Applicant already had an ID Card and is applying for a Driver's License 3 - Applicant is transferring his/her Driver's License from another state Your Choice: 6 - Select the type of application 1 - Applying for a brand new Driver's License 2 - Applicant already had an ID Card and is applying for a Driver's License 3 - Applicant is transferring his/her Driver's License from another state Your Choice: 8 - Select the type of application 1 - Applying for a brand new Driver's License 2 - Applicant already had an ID Card and is applying for a Driver's License 3 - Applicant is transferring his/her Driver's License from another state Your Choice: 3 First Name: Alexandria Last Name: McArthur Sex(F=Female/M=Male): M - Driver's License Class - All Non-commercial vehicles except motorcycles - Non-commercial vehicles up to and including 26,001/more lbs. - Cars, pick-up trucks, non-commercial vehicles 26,000 lbs. - Mopeds
A B C K
132 M - Motorcycles Your Choice: C Are you willing to be an Organ Donor(1=Yes/0=No)? 0 -=- Motor Vehicle Administration -=--- Driver's License Information --Type of Application: Transfer From Another State Full Name: Alexandria McArthur Sex: Male Class: C Organ Donor? No 3. Return to Visual C#
The for Statement The for statement is typically used to count a number of items. At its regular structure, it is divided in three parts. The first section specifies the starting point for the count. The second section sets the counting limit. The last section determines the counting frequency. The syntax of the for statement is: for(Start; End; Frequency) Statement; The Start expression is a variable assigned the starting value. This could be Count = 0; The End expression sets the criteria for ending the counting. An example would be Count < 24; which means that the counting would continue as long as the Count variable is less than 24. When the count is about to rich 24, because in this case 24 is excluded, the counting would stop. To include the counting limit, use the <= or >= comparison operators depending on how you are counting. The Frequency expression lets the compiler know how many numbers to add or subtract before continuing with the loop. This expression could be an increment operation such as ++Count. Here is an example that applies the for statement: using System; class NewProject { static void Main() { for(int Count = 0; Count <= 12; Count++) { Console.Write("Number "); Console.WriteLine(Count); } Console.WriteLine(); }
} A variable declared as the counter of a for loop is available only in that for loop. This means that the scope of the counting variable is confined only to the for loop. This allows different for loops to use the same counter variable. Here is an example:
133 using System; class NewProject { static void Main() { for(int Count = 0; Count <= 12; Count++) { Console.Write("Number "); Console.WriteLine(Count); } for(int Count = 10; Count >= 2; Count--) { Console.Write("Number "); Console.WriteLine(Count); } Console.WriteLine(); }
}
Techniques of Writing Conditional Statements Conditional Nesting A condition can be created inside of another to write a more effective statement. This is referred to as nesting one condition inside of another. Almost any condition can be part of another and multiple conditions can be included inside of others. As we have learned, different conditional statements are applied in specific circumstances. In some situations, they are interchangeable or one can be applied just like another, which becomes a matter of choice. Statements can be combined to render a better result with each playing an appropriate role. Here is an example of an if condition nested inside of a do...while loop: using System; class NewProject { static void Main() { char SittingDown; string SitDown; do { Console.Write("Are you sitting down now(y/n)? "); SitDown = Console.ReadLine(); SittingDown = char.Parse(SitDown); if( SittingDown != 'y' ) Console.WriteLine("Could you please sit down for the next exercise? "); } while( !(SittingDown == 'y') );
134
}
Console.WriteLine();
} Here is an example of running the program: Are you sitting down Could you please sit Are you sitting down Could you please sit Are you sitting down
now(y/n)? n down for the next exercise? now(y/n)? g down for the next exercise? now(y/n)? y
One of the reasons you would need to nest conditions is because one would lead to another. Sometimes, before checking one condition, another primary condition would have to be met. The ergonomic program we have been simulating so far is asking the user whether she is sitting down. Once the user is sitting down, you would write an exercise she would perform. Depending on her strength, at a certain time, one user will be tired and want to stop while for the same amount of previous exercises, another user would like to continue. Before continuing with a subsequent exercise, you may want to check whether the user would like to continue. Of course, this would be easily done with: using System; class NewProject { static void Main() { char SittingDown; string SitDown; do { Console.Write("Are you sitting down now(y/n)? "); SitDown = Console.ReadLine(); SittingDown = char.Parse(SitDown); if( SittingDown != 'y' ) Console.WriteLine("Could you please sit down for the next exercise? "); } while( !(SittingDown == 'y') ); Console.Write("Wonderful. Now we will continue today's exercise..."); Console.WriteLine("\n...\nEnd of exercise"); char WantToContinue; Console.Write("\nDo you want to continue(y=Yes/n=No)? "); string ToContinue = Console.ReadLine(); WantToContinue = char.Parse(ToContinue); }
Console.WriteLine();
} If the user answers No, you can stop the program. If she answers Yes, you would need to continue the program with another exercise. Because the user answered Yes, the subsequent exercise would be included in the previous condition because it does not apply for a user who
135
wants to stop. In this case, one “if” could be inserted inside of another. Here is an example: using System; class NewProject { static void Main() { char SittingDown; string SitDown; do { Console.Write("Are you sitting down now(y/n)? "); SitDown = Console.ReadLine(); SittingDown = char.Parse(SitDown); if( SittingDown != 'y' ) Console.WriteLine("Could you please sit down for the next exercise? ");
}while( SittingDown != 'y' ); Console.WriteLine("Wonderful. Now we will continue today's
exercise...");
Console.WriteLine("\n...\nEnd of exercise\n"); char WantToContinue; Console.Write("\nDo you want to continue(1=Yes/0=No)? "); string ToContinue = Console.ReadLine(); WantToContinue = char.Parse(ToContinue); if(WantToContinue == '1') { char LayOnBack; Console.WriteLine("Good. For the next exercise, you should lay
on your back");
Console.Write("Are you laying on your back(1=Yes/0=No)? "); string Lay = Console.ReadLine(); LayOnBack = char.Parse(Lay); if(LayOnBack == '1') Console.WriteLine("Great.\nNow we will start the next
exercise.");
else tired...");
} else
Console.WriteLine("\nWell, it looks like you are getting
Console.WriteLine("We had enough today");
Console.WriteLine("We will stop the session now\nThanks.\n"); }
}
136
Practical Learning: Nesting Conditions 1. Change the file as follows: using System; enum TypeOfApplication { NewDriversLicense = 1, UpgradeFromIDCard, TransferFromAnotherState }; class Exercise { static void Main() { . . . No Change Console.WriteLine(" -=- Motor Vehicle Administration -=-"); Console.WriteLine(" --- Driver's License Application ---"); do {
Console.WriteLine(" - Select the type of application -"); Console.WriteLine("1 - Applying for a brand new Driver's License"); Console.WriteLine("2 - Applicant already had an ID Card and is applying for a Driver's
License"); state");
Console.WriteLine("3 - Applicant is transferring his/her Driver's License from another Console.Write("Your Choice: "); type = int.Parse(Console.ReadLine());
if( type > 3 ) Console.WriteLine("Please enter a valid number as 1, 2, or 3"); } while(type > 3); . . . No Change
}
return 0;
} 2. Save, compile, and test the program
The break Statement The break statement is used to stop a loop for any reason or condition the programmer considers fit. The break statement can be used in a while condition to stop an ongoing action. The syntax of the break statement is simply: break; Although made of only one word, the break statement is a complete statement. Therefore, it can (and should always) stay on its own line (this makes the program easy to read). The
137
break statement applies to the most previous conditional statement to it, provided that previous statement is applicable. The break statement is typically used to handle the cases in a switch statement as we saw it in the previous lesson. Besides the switch statement, the break statement can also be used in other conditional statements. For example, you can use a break statement inside of a for loop to interrupt its count. The following program would display letter from d to n but it is interrupted by a break when it encounters k: using System; class Exercise { static void Main() { for (char c = 'd'; c <= 'n'; c++) { if (c == 'k') break; Console.WriteLine(c); }
}
Console.WriteLine(); return 0;
} This would produce: d e f g h i j The break statement can also be used in a do…while or a for loop the same way.
The continue Statement The continue statement uses the following formula: continue; When processing a loop, if the statement finds a false value, you can use the continue statement inside of a while, do…while or a for conditional statements to ignore the subsequent statement or to jump from a false Boolean value to the subsequent valid value, unlike the break statement that would exit the loop. Like the break statement, the continue keyword applies to the most previous conditional statement and should stay on its own line. The following programs asks the user to type 4 positive numbers and calculates the sum of the numbers by considering only the positive ones. If the user types a negative number, the program manages to ignore the numbers that do not fit in the specified category:
138 using System; class Exercise { static void Main() { // Declare necessary variables double Number, Sum = 0; string Nbr; // Request 4 positive numbers from the user Console.WriteLine("Type 4 positive numbers."); // Make sure the user types 4 positive numbers for( int Count = 1; Count <= 4; Count++ ) { Console.Write("Number: "); Nbr = Console.ReadLine(); Number = double.Parse(Nbr); // If the number typed is not positive, ignore it if( Number < 0 ) continue;
}
// Add each number to the sum Sum += Number;
// Display the sum Console.WriteLine("Sum of the numbers you entered = {0}\n", Sum); return 0; }
} This would produce:
Type 4 positive numbers. Number: 24.55 Number: 826.08 Number: 1450.85 Number: 262.58 Sum of the numbers you entered = 2564.06
The goto Statement
The goto statement allows a program execution to jump to another section of the function in which it is being used. In order to use the goto statement, insert a name on a particular section of your function so you can refer to that name. The name, also called a label, is made of one word and follows the rules we have learned about C# names (the name can be anything), then followed by a colon. The following program uses a for loop to count from 0 to 12, but when it encounters 5, it jumps to a designated section of the program: using System; class NewProject {
139 static void Main() { for(int Count = 0; Count <= 12; ++Count) { Console.WriteLine("Count {0}", Count); if( Count == 5 ) goto MamaMia; } MamaMia: Console.WriteLine("\nStopped at 5"); Console.WriteLine(); }
}
This would produce: Count Count Count Count Count Count
0 1 2 3 4 5
Stopped at 5
Logical Operations on Statements Introduction The conditional statements we have used so far were applied to single situations. You can combine statements using techniques of logical operations to create more complex and complete expressions. One way to do this is by making sure that two conditions are met for the whole expression to be true. On the other hand, one or the other of two conditions can produce a true condition, as long as one of them is true. This is done with logical conjunction or disjunction. In the beginning of the previous lesson, we described ways to write clear, simple, and logical statements. The techniques are even more important when combining statements because, once again, you should be able to make a decision based on a short, truthful, and clear statement.
Logical Conjunction: AND One of the operations used in combining two statements consists of validating an expression made of two parts only if both parts of the statement are true. Imagine that a sport camp states on an application form that an interested candidate must be "a man at least 18 years old". This condition can be divided in two statements as follows: 1. A - The applicant is a man 2. B - The applicant is at least 18 years old The program to process an application can look like this:
140 using System; class SportCamp { static void Main() { string FullName; int Gender; int Age; Console.WriteLine("Enter the following pieces of information"); Console.Write("Full Name: "); FullName = Console.ReadLine(); Console.Write("Gender(1=Male/0=Female): "); Gender = int.Parse(Console.ReadLine()); Console.Write("Age: "); Age = int.Parse(Console.ReadLine()); Console.WriteLine(); }
}
Here is an example of running the program: Enter the following pieces of information Full Name: Ernestine Monay Gender(1=Male/0=Female): 6 Age: 16 Every time a new person has filled an application, his or her information would be evaluated according to the above statements: •
If the applicant is a man, the first statement, represented here as A would be true
•
If the applicant is 18 or older, the second statement will be rendered true.
If we evaluate these statement separately, we can tabulate them as follows: A
B
Suppose an applicant answers the first question as being a female, but the statement on the application said that an applicant must be a male. Once this statement produces a false result. We don't care how old the applicant is, the whole statement would be false. This would produce the following table: A False
B Don't Care
Statement False
Here is an example of processing and validating the first question: using System; class SportCamp
141 { static void Main() { string FullName; int Gender; int Age; Console.WriteLine("Enter the following pieces of information"); Console.Write("Full Name: "); FullName = Console.ReadLine(); Console.Write("Gender(1=Male/0=Female): "); Gender = int.Parse(Console.ReadLine()); if( Gender == 1 ) { // If the applicant is a man, then we can continue Console.Write("Age: "); Age = int.Parse(Console.ReadLine()); } else // If the applicant is not a man, let the applicant know Console.WriteLine("You don't qualify"); Console.WriteLine(); }
} Here is an example of running the program:
Enter the following pieces of information Full Name: Samuel Golfer Gender(1=Male/0=Female): 1 Age: 16 Here is another example of running the same program: Enter the following pieces of information Full Name: Germain Gobb Gender(1=Male/0=Female): 6 You don't qualify If an application answers the first question and indicates that he is a man, then we can process the second question. If the applicant indicates that he is younger than 18, the second statement is false. Consequently, the applicant doesn't qualify. The process this second question, we can nest a condition and change the program as follows: using System; class SportCamp { static void Main() { string FullName; int Gender; int Age; Console.WriteLine("Enter the following pieces of information"); Console.Write("Full Name: ");
142 FullName = Console.ReadLine(); Console.Write("Gender(1=Male/0=Female): "); Gender = int.Parse(Console.ReadLine()); if( Gender == 1 ) { // If the applicant is a man, then we can continue Console.Write("Age: "); Age = int.Parse(Console.ReadLine()); if( Age < 18 ) Console.WriteLine("You are not old enough!");
} else // If the applicant is not a man, let the applicant know Console.WriteLine("You don't qualify"); Console.WriteLine(); }
} Here is an example of running the program:
Enter the following pieces of information Full Name: Joseph Davis Gender(1=Male/0=Female): 5 You don't qualify Here is another example of running the same program: Enter the following pieces of information Full Name: Thomas Lemm Gender(1=Male/0=Female): 1 Age: 16 You are not old enough! This would produce the following table: A Don't Care
B False
Statement False
In the same way, if the applicant answers to be a female and younger than 18, the whole statement is still false. This would produce the following table: A False
B False
Statement False
As a consequence, an applicant qualifies only if he is a male and at least 18. The program that evaluates this c an be written as follows: using System; class SportCamp { static void Main() { string FullName;
143 int Gender; int Age; Console.WriteLine("Enter the following pieces of information"); Console.Write("Full Name: "); FullName = Console.ReadLine(); Console.Write("Gender(1=Male/0=Female): "); Gender = int.Parse(Console.ReadLine()); if( Gender == 1 ) { // If the applicant is a man, then we can continue Console.Write("Age: "); Age = int.Parse(Console.ReadLine()); if( Age < 18 ) Console.WriteLine("You are not old enough!"); else Console.WriteLine("Your application is valid"); } else // If the applicant is not a man, let the applicant know Console.WriteLine("You don't qualify"); }
Console.WriteLine();
} This shows that an applicant qualifies only if both statements are true. In the above section, to evaluate related statements, we proceeded by nesting them, which made our program complete but longer. To process this type of related statements, you can combine them using the Boolean AND operator. Based on this, a statement such as "The applicant must be a man at least 18 years old" can be segmented in two statements joined as follows: "The applicant is a man" AND "The applicant is at least 18 years old" In C#, the logical conjunction is performed using the && operator. A combination of A AND B can be represented as follows: A
B
A && B
The expression that evaluates this combined statement can be written as follows: using System; class SportCamp { static void Main() { string FullName; int Gender; int Age; Console.WriteLine("Enter the following pieces of information");
144 Console.Write("Full Name: "); FullName = Console.ReadLine(); Console.Write("Gender(1=Male/0=Female): "); Gender = int.Parse(Console.ReadLine()); Console.Write("Age: "); Age = int.Parse(Console.ReadLine()); if( Gender == 1 && Age >= 18 ) Console.WriteLine("Your application is valid"); else Console.WriteLine("You don't qualify"); Console.WriteLine(); }
}
Based on the rules of operator, this logical operation will work. The compiler will evaluate the "Gender == 1" condition first, then it will evaluate the "Age >= 18" condition, then it will combine the first to the second. Sometime this expression can appear confusing to read. If you want, you can include each part of the combination in its own parentheses. Here is an example: using System; class SportCamp { static void Main() { string FullName; int Gender; int Age; Console.WriteLine("Enter the following pieces of information"); Console.Write("Full Name: "); FullName = Console.ReadLine(); Console.Write("Gender(1=Male/0=Female): "); Gender = int.Parse(Console.ReadLine()); Console.Write("Age: "); Age = int.Parse(Console.ReadLine()); if( (Gender == 1) && (Age >= 18) ) Console.WriteLine("Your application is valid"); else Console.WriteLine("You don't qualify"); Console.WriteLine(); }
}
This makes the program easier to read. •
If the current applicant is a woman, our first statement, represented as A, is false
•
If the same applicant is younger than 18, our second statement, represented as B, is false
•
If both statements are false, the combined statement, represented as A&&B, or C, is
145
false. This can be represented in a truth table as follows: A False
B False
A && B False
Based on this table, here is an example of running the program: Enter the following pieces of information Full Name: Germain Asse Gender(1=Male/0=Female): 0 Age: 16 You don't qualify •
If the current applicant is a woman, our first statement is false
•
If the same applicant is at least 18 years old, our second statement is true
•
If the first statement is false and the second is true, the combined statement is false
This can be represented in a truth table as follows: A False
B True
A && B False
Based on this table, here is an example of running the program: Enter the following pieces of information Full Name: Germain Asse Gender(1=Male/0=Female): 0 Age: 24 You don't qualify In the same way •
If the current applicant is a man, our first statement is true
•
If the same applicant is at least 18 years old, our second statement is false
•
If the first statement is true and the second is false, the combined statement is false
This can be represented in a truth table as follows: A True
B False
A && B False
Based on this table, here is an example of running the program: Enter the following pieces of information Full Name: Germain Asse Gender(1=Male/0=Female): 1 Age: 14 You don't qualify •
If the current applicant is a man, our first statement is true
•
If the same applicant is at least 18 years old, our second statement is true
146 •
If both statements are true, the combined statement is true.
This results in: A True
B True
A && B True
Based on this table, here is an example of running the program: Enter the following pieces of information Full Name: Germain Asse Gender(1=Male/0=Female): 1 Age: 22 Your application is valid The above tables can be combined into one as follows: A False False True True
B False True False True
A && B False False False True
Practical Learning: Using the Logical AND Operator 1. To use logical conjunction, change the program as follows: using System; enum TypeOfApplication { NewDriversLicense = 1, UpgradeFromIDCard, TransferFromAnotherState }; class Exercise { static void Main() { TypeOfApplication AppType; int type; string FirstName, LastName; string OrganDonorAnswer; char Sex; string Gender; char DLClass; Console.WriteLine(" -=- Motor Vehicle Administration -=-"); Console.WriteLine(" --- Driver's License Application ---");
147
do {
Driver's License"); from another state");
Console.WriteLine(" - Select the type of application -"); Console.WriteLine("1 - Applying for a brand new Driver's License"); Console.WriteLine("2 - Applicant already had an ID Card and is applying for Console.WriteLine("3 - Applicant is transferring his/her Driver's License Console.Write("Your Choice: "); type = int.Parse(Console.ReadLine());
if( type > 3 ) Console.WriteLine("Please enter a valid number as 1, 2, or 3"); Console.WriteLine(""); } while(type > 3); Console.Write("First Name: "); FirstName = Console.ReadLine(); Console.Write("Last Name: "); LastName = Console.ReadLine(); do {
Console.Write("Sex(F=Female/M=Male): "); Sex = char.Parse(Console.ReadLine()); if( (Sex != 'f') && (Sex != 'F') && (Sex != 'm') && (Sex != 'M') ) Console.WriteLine("\nInvalid Answer - Try Again"); } while( (Sex != 'f') && (Sex != 'F') && (Sex != 'm') && (Sex != 'M') ); if( Sex == 'f' ) Gender = "Female"; else if( Sex == 'F' ) Gender = "Female"; else if( Sex == 'm' ) Gender = "Male"; else if( Sex == 'M' ) Gender = "Male"; else Gender = "Unknown";
lbs.");
Console.WriteLine(" - Driver's License Class -"); Console.WriteLine("A - All Non-commercial vehicles except motorcycles"); Console.WriteLine("B - Non-commercial vehicles up to and including 26,001/more
Console.WriteLine("C - Cars, pick-up trucks, non-commercial vehicles 26,000 lbs.") Console.WriteLine("K - Mopeds"); Console.WriteLine("M - Motorcycles"); Console.Write("Your Choice: "); DLClass = char.Parse(Console.ReadLine()); do { Console.Write("Are you willing to be an Organ Donor(y=Yes/n=No)? "); OrganDonorAnswer = Console.ReadLine(); if( (OrganDonorAnswer != "y") && (OrganDonorAnswer != "Y") &&
148 (OrganDonorAnswer != "n") && (OrganDonorAnswer != "N") ) Console.WriteLine("\nInvalid Answer"); } while( (OrganDonorAnswer != "y") && (OrganDonorAnswer != "Y") && (OrganDonorAnswer != "n") && (OrganDonorAnswer != "N") ); Console.WriteLine("\n -=- Motor Vehicle Administration -=-"); Console.WriteLine(" --- Driver's License Information ---"); AppType = (TypeOfApplication)type; Console.Write("Type of Application: "); switch(AppType) { case TypeOfApplication.NewDriversLicense: Console.WriteLine("New Driver's License"); break; case TypeOfApplication.UpgradeFromIDCard: Console.WriteLine("Upgrade From Identity Card"); break; case TypeOfApplication.TransferFromAnotherState: Console.WriteLine("Transfer From Another State"); break; default: Console.WriteLine("Not Specified"); break; } Console.WriteLine("Full Name: {0} {1}", FirstName, LastName); Console.WriteLine("Sex: {0}", Gender); switch(DLClass) { case 'a': case 'A': Console.WriteLine("Class: break; case 'b': case 'B': Console.WriteLine("Class: break; case 'c': case 'C': Console.WriteLine("Class: break; case 'k': case 'K': Console.WriteLine("Class: break; case 'm': case 'M': Console.WriteLine("Class: break; default: Console.WriteLine("Class: break; }
A");
B");
C");
K");
M"); Unknown");
149
Console.Write("Organ Donor? "); Console.WriteLine(OrganDonorAnswer == "1" ? "Yes" : (OrganDonorAnswer == "0" ? "No "Invalid Answer")); return 0; }
}
2. Save, compile, and test the program. Here is an example: -=- Motor Vehicle Administration -=--- Driver's License Application --- Select the type of application 1 - Applying for a brand new Driver's License 2 - Applicant already had an ID Card and is applying for a Driver's License 3 - Applicant is transferring his/her Driver's License from another state Your Choice: 6 Please enter a valid number as 1, 2, or 3 - Select the type of application 1 - Applying for a brand new Driver's License 2 - Applicant already had an ID Card and is applying for a Driver's License 3 - Applicant is transferring his/her Driver's License from another state Your Choice: 3 First Name: Larry Last Name: Edmonston Sex(F=Female/M=Male): g Invalid Answer - Try Again Sex(F=Female/M=Male): m - Driver's License Class A - All Non-commercial vehicles except motorcycles B - Non-commercial vehicles up to and including 26,001/more lbs. C - Cars, pick-up trucks, non-commercial vehicles 26,000 lbs. K - Mopeds M - Motorcycles Your Choice: b Are you willing to be an Organ Donor(1=Yes/0=No)? 8 Invalid Answer Are you willing to be an Organ Donor(1=Yes/0=No)? 1 -=- Motor Vehicle Administration -=--- Driver's License Information --Type of Application: Transfer From Another State Full Name: Larry Edmonston Sex: Male Class: B Organ Donor? Yes Press any key to continue 3. Return to Visual C#
150
Logical Disjunction: OR Imagine you are looking for a job and you come to an ad that states, "Programmer needed, an applicant should be a Microsoft Certified Application Developer (MCAD). If you are not an MCAD, you must have at least a bachelor's degree". This announcement can be resumed to the following statement: "The applicant must either be an MCAD or must have a bachelor's degree". It can be further segmented in two sub-statements as follows: •
The applicant is an MCAD
•
The application has a bachelor's degree
The program to process an application can appear as follows: using System; class JobApplication { static void Main() { string FullName; int MCAD; int Degree; Console.WriteLine("Enter the following pieces of information"); Console.Write("Applicant's Name: "); FullName = Console.ReadLine(); Console.Write("Are you an MCAD (1=Yes/0=No)? "); MCAD = int.Parse(Console.ReadLine()); Console.Write("Do you hold a bachelor's degree (1=Yes/0=No)? "); Degree = int.Parse(Console.ReadLine()); Console.WriteLine(); }
}
Here is an example of running the program: Enter the following pieces of information Applicant's Name: Paul Brownies Are you an MCAD (1=Yes/0=No)? 4 Do you hold a bachelor's degree (1=Yes/0=No)? 6 When a new applicant applies for a job, his or her information is evaluated: •
If the applicant is an MCAD, the first statement, represented here as A, is true
•
If the applicant has a bachelor's degree, the second statement, represented as B, is true
If an applicant indicates in the first question that he or she is an MCAD, we wouldn't care about the second question. This resulting statement can be represented as follows: A True
B Don't Care
Statement True
Here is an example of processing and validating the first question:
151 using System; class JobApplication { static void Main() { string FullName; int MCAD; int Degree; Console.WriteLine("Enter the following pieces of information"); Console.Write("Applicant's Name: "); FullName = Console.ReadLine(); Console.Write("Are you an MCAD (1=Yes/0=No)? "); MCAD = int.Parse(Console.ReadLine()); if( MCAD == 1 ) Console.WriteLine("Since you are an MCAD, you qualify"); }
Console.WriteLine();
} Here is an example of running the program: Enter the following pieces of information Applicant's Name: Saul Kemmel Are you an MCAD (1=Yes/0=No)? 4 Here is another example of running the same program: Enter the following pieces of information Applicant's Name: Saul Kemmel Are you an MCAD (1=Yes/0=No)? 1 Since you are an MCAD, you qualify If the answer to the first question indicates that an applicant is not an MCAD, then we would be interested in the answer to the second question. If the second answers shows that the applicant has a bachelor's degree, then he or she qualifies. In fact in this case, the answer to the first question would not be important: A Don't Care
B True
Statement True
The second question can be addressed as follows: using System; class JobApplication { static void Main() { string FullName; int MCAD; int Degree; Console.WriteLine("Enter the following pieces of information");
152 Console.Write("Applicant's Name: "); FullName = Console.ReadLine(); Console.Write("Are you an MCAD (1=Yes/0=No)? "); MCAD = int.Parse(Console.ReadLine()); Console.Write("Do you hold a bachelor's degree (1=Yes/0=No)? "); Degree = int.Parse(Console.ReadLine()); Console.WriteLine(); if( MCAD == 1 ) Console.WriteLine("Since you are an MCAD, you qualify"); if( Degree == 1 ) Console.WriteLine("Since you have the necessary degree, you qualify"); Console.WriteLine(); }
} Here is an example of running the program:
Enter the following pieces of information Applicant's Name: Annie Baugh Are you an MCAD (1=Yes/0=No)? 8 Do you hold a bachelor's degree (1=Yes/0=No)? 1 Since you have the necessary degree, you qualify In the same way, if an applicant is an MCAD and holds a bachelor's degree, he or she still qualifies. This produce the following table: A True
B True
Statement True
Based on this, here is an example of running the program: Enter the following pieces of information Applicant's Name: Jamie Konlo Are you an MCAD (1=Yes/0=No)? 1 Do you hold a bachelor's degree (1=Yes/0=No)? 1 Since you are an MCAD, you qualify Since you have the necessary degree, you qualify Therefore, if an application either is an MCAD or has a degree or fulfills both criteria, he or she qualifies. If a candidate neither is an MCAD nor has the degree, he or she cannot have the job. This can be resumed as follows: A False
B False
Statement False
Writing both statements separately can appear redundant. Instead, if you are evaluating two statements but the truthfulness of only one is enough to render both as true, you can perform a Boolean disjunction operation. This is also called an OR operator. Using this operator, our two statements can be combined as "The applicant is an MCAD" OR "The applicant has a bachelor's
153
degree". In C#, the logical disjunction is performed using the || operator. A combination of A || B can be represented as follows: A True False True False
B False True True False
A || B True True True False
The expression that evaluates this combined statement can be written as follows: using System; class JobApplication { static void Main() { string FullName; int MCAD; int Degree; Console.WriteLine("Enter the following pieces of information"); Console.Write("Applicant's Name: "); FullName = Console.ReadLine(); Console.Write("Are you an MCAD (1=Yes/0=No)? "); MCAD = int.Parse(Console.ReadLine()); Console.Write("Do you hold a bachelor's degree (1=Yes/0=No)? "); Degree = int.Parse(Console.ReadLine()); Console.WriteLine(); if( MCAD == 1 || Degree == 1 ) Console.WriteLine("Since you are an MCAD OR you have the necessary degree, you qualify"); else Console.WriteLine("We will get back to you"); }
Console.WriteLine();
} Once again, based on the rules of operators precedence, the "MCAD == 1 || Degree == 1" expression will work fine. If it appears difficult to read, you can include each part in its parentheses as (MCAD == 1) || (Degree == 1). Here is an example of running the program: Enter the following pieces of information Applicant's Name: Sally Kirkfield Are you an MCAD (1=Yes/0=No)? 1 Do you hold a bachelor's degree (1=Yes/0=No)? 8 Since you are an MCAD OR you have the necessary degree, you qualify
154 Here is another example of running the same program: Enter the following pieces of information Applicant's Name: Leslie Stanislaw Are you an MCAD (1=Yes/0=No)? 0 Do you hold a bachelor's degree (1=Yes/0=No)? 0 We will get back to you
Practical Learning: Using the Logical OR Operator 1. To write logical disjunctions, change the program as follows: using System; enum TypeOfApplication { NewDriversLicense = 1, UpgradeFromIDCard, TransferFromAnotherState }; class Exercise { static void Main() { TypeOfApplication AppType; int type; string FirstName, LastName; string OrganDonorAnswer; char Sex; string Gender = null; char DLClass; Console.WriteLine(" -=- Motor Vehicle Administration -=-"); Console.WriteLine(" --- Driver's License Application ---"); do {
Console.WriteLine(" - Select the type of application -"); Console.WriteLine("1 - Applying for a brand new Driver's License"); Console.WriteLine("2 - Applicant already had an ID Card and is applying for a Driver's License"); Console.WriteLine("3 - Applicant is transferring his/her Driver's License from another state"); Console.Write("Your Choice: "); type = int.Parse(Console.ReadLine()); if( (type < 1) || (type > 3) ) Console.WriteLine("\nPlease enter a valid number as 1, 2, or 3"); } while( (type < 1) || (type > 3) ); Console.WriteLine(); Console.Write("First Name: "); FirstName = Console.ReadLine(); Console.Write("Last Name: ");
155 LastName = Console.ReadLine(); do {
Console.Write("Sex(F=Female/M=Male): "); Sex = char.Parse(Console.ReadLine()); if( (Sex != 'f') && (Sex != 'F') && (Sex != 'm') && (Sex != 'M') ) Console.WriteLine("\nInvalid Answer - Try Again"); } while( (Sex != 'f') && (Sex != 'F') && (Sex != 'm') && (Sex != 'M') ); if( (Sex == 'f') Gender = else if( (Sex == Gender =
|| (Sex == 'F') ) "Female"; 'm') || (Sex == 'M') ) "Male";
Console.WriteLine();
lbs.");
Console.WriteLine(" - Driver's License Class -"); Console.WriteLine("A - All Non-commercial vehicles except motorcycles"); Console.WriteLine("B - Non-commercial vehicles up to and including 26,001/more
Console.WriteLine("C - Cars, pick-up trucks, non-commercial vehicles 26,000 lbs.") Console.WriteLine("K - Mopeds"); Console.WriteLine("M - Motorcycles"); Console.Write("Your Choice: "); DLClass = char.Parse(Console.ReadLine()); Console.WriteLine(); do { Console.Write("Are you willing to be an Organ Donor(y=Yes/n=No)? "); OrganDonorAnswer = Console.ReadLine(); if( (OrganDonorAnswer != "y") && (OrganDonorAnswer != "Y") && (OrganDonorAnswer != "n") && (OrganDonorAnswer != "N") ) Console.WriteLine("\nInvalid Answer"); } while( (OrganDonorAnswer != "y") && (OrganDonorAnswer != "Y") && (OrganDonorAnswer != "n") && (OrganDonorAnswer != "N") ); Console.WriteLine("\n======================================="); Console.WriteLine(" -=- Motor Vehicle Administration -=-"); Console.WriteLine(" --- Driver's License Information ---"); AppType = (TypeOfApplication)type; Console.Write("Type of Application: "); switch(AppType) { case TypeOfApplication.NewDriversLicense: Console.WriteLine("New Driver's License"); break; case TypeOfApplication.UpgradeFromIDCard: Console.WriteLine("Upgrade From Identity Card"); break; case TypeOfApplication.TransferFromAnotherState: Console.WriteLine("Transfer From Another State"); break;
156 default: Console.WriteLine("Not Specified"); break; } Console.WriteLine("Full Name: Console.WriteLine("Sex:
{0} {1}", FirstName, LastName); {0}", Gender);
switch(DLClass) { case 'a': case 'A': Console.WriteLine("Class: break; case 'b': case 'B': Console.WriteLine("Class: break; case 'c': case 'C': Console.WriteLine("Class: break; case 'k': case 'K': Console.WriteLine("Class: break; case 'm': case 'M': Console.WriteLine("Class: break; default: Console.WriteLine("Class: break; }
A");
B");
C");
K");
M"); Unknown");
Console.Write("Organ Donor? "); if( (OrganDonorAnswer == "y") || (OrganDonorAnswer == "Y") ) Console.WriteLine("Yes"); else Console.WriteLine("No"); Console.WriteLine("=======================================");
}
Console.WriteLine(); return 0;
} 2. Save the file. Compile and test it. Here is an example: -=- Motor Vehicle Administration -=--- Driver's License Application --- Select the type of application 1 - Applying for a brand new Driver's License 2 - Applicant already had an ID Card and is applying for a Driver's License 3 - Applicant is transferring his/her Driver's License from another
157 state Your Choice: 0 Please enter a valid number as 1, 2, or 3 - Select the type of application 1 - Applying for a brand new Driver's License 2 - Applicant already had an ID Card and is applying for a Driver's License 3 - Applicant is transferring his/her Driver's License from another state Your Choice: 4 Please enter a valid number as 1, 2, or 3 - Select the type of application 1 - Applying for a brand new Driver's License 2 - Applicant already had an ID Card and is applying for a Driver's License 3 - Applicant is transferring his/her Driver's License from another state Your Choice: 1 First Name: Jocelyne Last Name: Aladiere Sex(F=Female/M=Male): D Invalid Answer - Try Again Sex(F=Female/M=Male): g Invalid Answer - Try Again Sex(F=Female/M=Male): f - Driver's License Class A - All Non-commercial vehicles except motorcycles B - Non-commercial vehicles up to and including 26,001/more lbs. C - Cars, pick-up trucks, non-commercial vehicles 26,000 lbs. K - Mopeds M - Motorcycles Your Choice: m Are you willing to be an Organ Donor(y=Yes/n=No)? d Invalid Answer Are you willing to be an Organ Donor(y=Yes/n=No)? p Invalid Answer Are you willing to be an Organ Donor(y=Yes/n=No)? Y ======================================= -=- Motor Vehicle Administration -=--- Driver's License Information --Type of Application: New Driver's License Full Name: Jocelyne Aladiere Sex: Female Class: M Organ Donor? Yes ======================================= 3. Close
158
Previous
Copyright © 2004-2005 FunctionX, Inc.
Next
The Members of the Main Class Introduction to Members Introduction to Methods One of the purposes of writing a program is to perform assignments. An assignment can also be called a function. The C# doesn't have the same notion of a function as did traditional and previous languages like C/C++, Pascal, etc. Instead, in C#, a function must belong to a class. Therefore, in C#, a function is a section whose job is to take care of an operation that would complement a class. Because a function in this case belongs to a particular class, the function is also called a method. From now on, the name method will be used for a function. C++ Note In C++, a function can be declared anywhere, making it distinct from a method. In C#, a function can be declared only inside of, or as a member of, a class Like everything else, a method must have a name. We will follow the same rules and conventions we defined for all names. An example of a method's name would be Welcome. To distinguish a method from a variable, it is always followed by parentheses, sometimes empty. Since a method is used to perform an assignment, its job is included between an opening curly bracket "{" and a closing curly bracket "}". Here is an example: using System;
159 class Exercise { Welcome() { } static void Main() { Console.WriteLine(); } } If the assignment performed by a method is long, you can use many lines to define its behavior. For this reason, each bracket can be typed on its own line. After a method has performed its assignment, it may provide a result. The result of a method is called a return value. Each return value follows a particular type based on one of the data types we reviewed on variables. Any time you create a method, the compiler needs to know the type of value that the method would return. The type of value that a method would return is specified on the left side of the method's name. Some, even many, of the methods used in your programs will not return a value after they have performed an assignment. When a method doesn't return a value, it is considered void. The return type of such a method is the void keyword. Here is an example: using System; class Exercise { void Welcome() { }
}
static void Main() { Console.WriteLine(); } In the exercises of this lesson, we will perform calculations for a cylinder with circular base: Figure
Areas Base Area = R * R * Pi Lateral Area = 2 * Pi * R * H Total Area = 2PiRH + 2PiR2
Practical Learning: Introducing Global Members 1. Start Microsoft Visual C# or Visual Studio .NET
Volume
PiR2H
160 2. On the main menu, click File -> New -> Project 3. If necessary, in the Project Types list of the New Project dialog box, click Visual C# Projects 4. In the Templates list, click Empty Project
5. In the Name text box, replace the name with Geometry1 and specify the desired path in the Location
6. Click OK 7. To create a source file for the project, on the main menu, click Project -> Add New Item... 8. In the Add New Item dialog box, in the Templates list, click Code File
9. In the Name text box, delete the suggested name and replace it with Exercise 10. Click Open 11. In the empty file, type the following: using System; namespace GeometricFormulas { class Cylinder { static void Main() { Console.WriteLine(); } } } 12. Save the file
Static Methods Unlike some other languages like C/C++, Pascal, Visual Basic, etc, but like Java, C# doesn't have the notion of global function: every method must belong to a class. For this reason, every program uses at least one class and we call this primary class, the main class. Because of this feature of the language, it imposes some rules on the way methods can be called. If you create a method in the main class of your project, you should indicate that the method will always belong to this main class. The method must be created as static. To define a method as static, type the static keyword to its left. Here is an example: using System; class Exercise { static void Welcome() { } static void Main() { Console.WriteLine();
161
}
} As we have used the Main() function so far, the behavior of a method is defined between its delimiting curly brackets. The section inside the curly brackets is called the body of a method. In the body of the method, you can simply display a sentence. Here is an example:
using System; class Exercise { static void Welcome() { Console.WriteLine("Welcome to the Wonderful World of C#"); } static void Main() { Console.WriteLine(); } } In the same way, you can use a method to perform any other assignment. After creating a method, you can use it where needed. Using a method is also referred to as calling it. If you create a simple method like the above Welcome(), to call it, type its name followed by parentheses and ending with a semi-colon. Here is an example: using System; class Exercise { static void Welcome() { Console.WriteLine("Welcome to the Wonderful World of C#"); } static void Main() { Welcome(); } }
Console.WriteLine();
Practical Learning: Creating a Static Method 1. To define a static method, change the file as follows: using System; class Cylinder { static void ProcessCylinder() { Console.WriteLine("Cylinder Characteristics"); }
162 static void Main() { ProcessCylinder(); Console.WriteLine(); }
}
2. To execute the application, on the main menu, click Debug -> Start Without Debugging 3. Return to Visual C#
Local Variables In the body of a method, you can also declare variables that would be used internally. A variable declared in the body is referred to as a local variable. It cannot be accessed outside of the method it belongs to. After declaring a local variable, it is made available to the method and you can use it as you see fit, for example, you can assign it a value prior to using it.
Practical Learning: Using a Method's Local Variables 1. To declare and use local variables of a method, change the static method as follows: using System; namespace GeometricFormulas { class Cylinder { static void ProcessCylinder() { double Radius, Height; double BaseArea, LateralArea, TotalArea; double Volume; Console.WriteLine("Enter the dimensions of the cylinder");
Radius); Height;
Console.Write("Radius: "); Radius = double.Parse(Console.ReadLine()); Console.Write("Height: "); Height = double.Parse(Console.ReadLine()); BaseArea = Radius * Radius * Math.PI; LateralArea = 2 * Math.PI * Radius * Height; TotalArea = 2 * Math.PI * Radius * (Height + Volume
= Math.PI * Radius * Radius *
Console.WriteLine("\nCylinder Characteristics"); Console.WriteLine("Radius: {0}", Radius); Console.WriteLine("Height: {0}", Height); Console.WriteLine("Base: {0:F}", BaseArea); Console.WriteLine("Lateral: {0:F}", LateralArea);
Console.WriteLine("Total:
{0:F}", TotalArea);
163 Console.WriteLine("Volume:
{0:F}", Volume);
} static void Main() { ProcessCylinder(); }
Console.WriteLine();
}
}
2. Execute the application. Here is an example: Enter the dimensions of the cylinder Radius: 38.64 Height: 22.48 Cylinder Radius: Height: Base: Lateral: Total: Volume:
Characteristics 38.64 22.48 4690.55 5457.75 14838.85 105443.65
3. Return to Visual C#
A Method that Returns a Value If a method has carried an assignment and must make its result available to other methods or other classes, the method must return a value and cannot be void. To declare a method that returns a value, provide its return type to the left of its name. Here is an example: using System; class Exercise { static double Operation() { } static void Main() { } } After a method has performed its assignment, it must clearly demonstrate that it is returning a value. To do this, you use the return keyword followed by the value that the method is returning. The value returned must be of the same type specified as the return type of the method. Here is an example: using System; class Exercise {
164 static double Operation() { return 24.55; } static void Main() { } } A method can also return an expression, provided the expression produces a value that is conform to the return type. Here is an example: using System; class Exercise { static double Operation() { return 24.55 * 4.16; }
}
static void Main() { } When a method returns a value, the compiler considers such a method as if it were a regular value. This means that you can use Console.Write() or Console.WriteLine() to display its value. To do this, simply type the name of the method and its parentheses in the Console.Write() of the Console.WriteLine() methods' parentheses. Here is an example:
using System; class Exercise { static double Operation() { return 24.55; }
}
static void Main() { Console.WriteLine(Operation()); } In the same way, a method returns a value can be assigned to a variable of the same type.
Practical Learning: Returning a Value From a Method 1. To create methods that return values, change the program as follows: using System; namespace GeometricFormulas
165 { class Cylinder { static double GetRadius() { double rad; Console.Write("Radius: "); rad = double.Parse(Console.ReadLine()); return rad; } static double GetHeight() { double h; Console.Write("Height: "); h = double.Parse(Console.ReadLine()); return h; } static void ProcessCylinder() { double Radius, Height; double BaseArea, LateralArea, TotalArea; double Volume; Console.WriteLine("Enter the dimensions of the
cylinder");
Radius = GetRadius(); Height = GetHeight(); BaseArea = Radius * Radius * Math.PI; LateralArea = 2 * Math.PI * Radius * Height; TotalArea = 2 * Math.PI * Radius * (Height + Radius);
Volume
= Math.PI * Radius * Radius *
Height; Characteristics");
LateralArea); TotalArea);
Console.WriteLine("\nCylinder Console.WriteLine("Radius: Console.WriteLine("Height: Console.WriteLine("Base: Console.WriteLine("Lateral:
{0}", Radius); {0}", Height); {0:F}", BaseArea); {0:F}",
Console.WriteLine("Total:
{0:F}",
Console.WriteLine("Volume:
{0:F}", Volume);
} static void Main() { ProcessCylinder();
166
}
Console.WriteLine();
}
}
2. Save, compile, and test the file. Here is an example of running the program: Enter the dimensions of the cylinder Radius: 52.08 Height: 36.44 Cylinder Radius: Height: Base: Lateral: Total: Volume:
Characteristics 52.08 36.44 8521.02 11924.20 28966.25 310506.14
3. Return to Visual C#
Pseudo-Global Variables As mentioned with functions, C# doesn't have the notion of global variables (in C/C++, Visual Basic, Pascal, etc, a global variable is one that is declared outside of any class; such a variable is made available to any function, or even file, of the same program without being declared again where needed). Still, if you want to use the same variable in various methods of the main class, you can declare it outside of any method. The variable must be declared as static. That is, you must type the static keyword to its left when declaring it. Here is an example: using System; class Exercise { static double Length; static void Welcome() { Console.WriteLine("Welcome to the Wonderful World of C#"); } static void Main() { Welcome(); }
Console.WriteLine();
} After declaring such a variable, you can access from any method that belongs to the same class.
Practical Learning: Using Global Variables 1. To declare and use global variables, change the file as follows:
167
using System; namespace GeometricFormulas { class Cylinder { static double static double static double static double static double static double
Radius; Height; BaseArea; LateralArea; TotalArea; Volume;
static double GetRadius() { double rad; Console.Write("Radius: "); rad = double.Parse(Console.ReadLine()); }
return rad;
static double GetHeight() { double h; Console.Write("Height: "); h = double.Parse(Console.ReadLine()); }
return h;
static void ProcessCylinder() { Console.WriteLine("Enter the dimensions of the cylinder");
Radius = GetRadius(); Height = GetHeight(); BaseArea = Radius * Radius * Math.PI; LateralArea = 2 * Math.PI * Radius * Height; TotalArea = 2 * Math.PI * Radius * (Height +
Radius);
Volume
Height;
= Math.PI * Radius * Radius *
} static void ShowCylinder() { Console.WriteLine("\nCylinder Characteristics"); Console.WriteLine("Radius: {0}", Radius); Console.WriteLine("Height: {0}", Height); Console.WriteLine("Base: {0:F}", BaseArea);
168 Console.WriteLine("Lateral: {0:F}", LateralArea); }
Console.WriteLine("Total: Console.WriteLine("Volume:
{0:F}", TotalArea); {0:F}", Volume);
static void Main() { ProcessCylinder(); ShowCylinder(); } }
Console.WriteLine();
}
2. Save, compile, and test the file. Here is an example of running the program: Enter the dimensions of the cylinder Radius: 38.24 Height: 32.58 Cylinder Radius: Height: Base: Lateral: Total: Volume:
Characteristics 38.24 32.58 4593.94 7827.96 17015.85 149670.68
3. Return to Notepad
Methods and Conditional Statements Using Conditions in Functions The use of methods in a program allows you to isolate assignments and confine them to appropriate entities. While the methods take care of specific requests, you can provide them with conditional statements to validate what these methods do. There are no set rules to the techniques involved. Everything depends on the tasks at hand. To make effective use of methods, you should be very familiar with different data types because you will need to return the right value. Suppose you write an ergonomic program that needs to check different things including answers from the user in order to proceed. These various assignments can be given to methods that would simply hand the results to the Main() function that can, in turn, send these results to other functions for further processing. Here is an example: using System; public class NewProject { static char GetPosition() { char Position; string Pos;
169
do { Console.Write("Are you sitting down now(y/n)? "); Pos = Console.ReadLine();; Position = char.Parse(Pos); if( Position != 'y' && Position != 'Y' && Position != 'n' && Position != 'N' ) Console.WriteLine("Invalid Answer\n"); } while( Position != 'y' && Position != 'Y' && Position != 'n' && Position != 'N' ); }
return Position;
static void Main() { char Position; Position = GetPosition();
exercise?\n");
if( Position == 'n' || Position == 'N' ) Console.WriteLine("\nCould you please sit down for the next else
}
Console.WriteLine("\nWonderful!!!\n\n");
} Here is an example of running the program:
Are you sitting down now(y/n)? V Invalid Answer Are you sitting down now(y/n)? z Invalid Answer Are you sitting down now(y/n)? n Could you please sit down for the next exercise? Methods don't have to return a value in order to be involved with conditional statements. In fact, both issues are fairly independent. This means that, void and non-void methods can manipulate values based on conditions internal to them.
Practical Learning: Using Conditional Statements With Methods 1. To include conditional statements in your methods, change the file as follows: using System; namespace GeometricFormulas { class Cylinder {
170 static static static static static static
double double double double double double
Radius; Height; BaseArea; LateralArea; TotalArea; Volume;
static double GetRadius() { double rad; do { Console.Write("Radius: "); rad = double.Parse(Console.ReadLine()); if( rad < 0 ) Console.WriteLine("Please enter a positive number");
} while( rad < 0 ); return rad; } static double GetHeight() { double h; do { Console.Write("Height: "); h = double.Parse(Console.ReadLine()); if( h < 0 ) Console.WriteLine("Please enter a positive
number");
} while( h < 0 ); return h; } static void ProcessCylinder() { Console.WriteLine("Enter the dimensions of the cylinder"); Radius = GetRadius(); Height = GetHeight(); BaseArea LateralArea TotalArea Volume
= = = =
Radius * Radius * Math.PI; 2 * Math.PI * Radius * Height; 2 * Math.PI * Radius * (Height + Radius); Math.PI * Radius * Radius * Height;
} static void ShowCylinder() { Console.WriteLine("\nCylinder Characteristics"); Console.WriteLine("Radius: {0}", Radius); Console.WriteLine("Height: {0}", Height);
171
}
Console.WriteLine("Base: Console.WriteLine("Lateral: Console.WriteLine("Total: Console.WriteLine("Volume:
{0:F}", {0:F}", {0:F}", {0:F}",
BaseArea); LateralArea); TotalArea); Volume);
static void Main() { ProcessCylinder(); ShowCylinder(); } }
Console.WriteLine();
}
2. Save, compile, and test the file. Here is an example of running the program: Enter the dimensions of the cylinder Radius: -24.55 Please enter a positive number Radius: 24.55 Height: -18 Please enter a positive number Height: 18.75 Cylinder Radius: Height: Base: Lateral: Total: Volume:
Characteristics 24.55 18.75 1893.45 2892.23 6679.12 35502.11
3. Return to Notepad
Conditional Returns A method defined other than void must always return a value. Sometimes, a method will perform some tasks whose results would lead to different results. A method can return only one value (this is true for this context, but there are ways to pass arguments so that a method can return more than one value) but you can make it render a result depending on a particular behavior. If a method is requesting an answer from the user, since the user can provide different answers, you can treat each result differently. Imagine you write the following method: using System; public class NewProject { static string GetPosition() { char Position; Console.Write("Are you sitting down now(y/n)? ");
172 string Pos = Console.ReadLine(); Position = char.Parse(Pos);
}
if( Position == 'y' || Position == 'Y' ) return "Yes"; else if( Position == 'n' || Position == 'N' ) return "No";
static void Main() { string Answer; Answer = GetPosition(); Console.Write("\nAnswer = "); Console.WriteLine(Answer); }
} When running this program, you would receive an error. On paper, the function looks fine. If the user answers with y or Y, the function returns the string Yes. If the user answer with n or N, the function returns the string No. Unfortunately, this function has a problem: what if there is an answer that does not fit those we are expecting? The values that we have returned in the function conform only to the conditional statements and not to the function. Remember that in if(Condidion)Statement, the Statement executes only if the Condition is true. Here is what will happen. If the user answers y or Y, the function returns Yes and stops. If the user answers n or N, the function returns No, which also is a valid value. If the user enters another value (other than y, Y, n, or N), the execution of the function will not execute any of the returned statements and will not exit. This means that the execution will reach the closing curly bracket without encountering a return value. This would mean to the compiler that you wrote a nonvoid method that is supposed to return a value, but by the end of the method, it didn't return a value. That's why the compiler displays an error. The solution is to provide a return value so that, if the execution reaches the end of the function, it would still return something. Here is a solution to the problem:
using System; public class NewProject { static string GetPosition() { char Position; Console.Write("Are you sitting down now(y/n)? "); string Pos = Console.ReadLine(); Position = char.Parse(Pos); if( Position == 'y' || Position == 'Y' ) return "Yes"; else if( Position == 'n' || Position == 'N' ) return "No"; return "Invalid Answer"; } static void Main() {
173 string Answer;
}
Answer = GetPosition(); Console.Write("\nAnswer = "); Console.WriteLine(Answer);
} Here is an example of running the program: Are you sitting down now(y/n)? g Answer = Invalid Answer
void Methods and Conditional Returns So far, we have seen that void methods don't return a value. Still, the return keyword can be used in a void method. It allows you to exit a method before the last line if you judge it necessary. Suppose that you ask a question in a method or validate a condition. Once the condition is valid, you may not see any reason to continue further. In this case, you would like to interrupt the flow in that method and continue with the next task in another method. To get an early exit from a method, where you judge it necessary, type the return keyword followed by a semi-colon. Of course, since this is usually used to value a condition, the return keyword can be typed at the end of a conditional statement.
Previous
Copyright © 2004-2005 FunctionX, Inc.
Next
Methods and their Parameters Arguments Overview of an Argument As we saw in the previous lesson, a method performs an assignment that completes the operations of a class. The methods we used in the previous lesson relied on global variables to exchange information with other sections of the program. Sometimes, a method would need one or more values in order to carry its assignment. The particularity of such a value or such values is that another method that calls this one must supply the needed values. When a method needs a value to complete its assignment, such a value is called an argument.
Practical Learning: Introducing Arguments 1. Start Microsoft Visual C# or Visual Studio .NET
174 2. On the main menu, click File -> New -> Project 3. If necessary, in the Project Types list of the New Project dialog box, click Visual C# Projects 4. In the Templates list, click Empty Project
5. In the Name text box, replace the name with Geometry2 and specify the desired path in the Location
6. Click OK 7. To create a source file for the project, on the main menu, click Project -> Add New Item... 8. In the Add New Item dialog box, in the Templates list, click Code File
9. In the Name text box, delete the suggested name and replace it with Exercise 10. Click Open 11. In the empty file, type the following: using System; namespace GeometricFormulas { class Cylinder { static double static double static double static double static double static double
Radius; Height; BaseArea; LateralArea; TotalArea; Volume;
static double GetRadius() { double rad; do { Console.Write("Radius: "); rad = double.Parse(Console.ReadLine()); if( rad < 0 ) Console.WriteLine("Please enter a positive number"); } while( rad < 0 ); }
return rad;
static double GetHeight() { double h; do {
Console.Write("Height: "); h = double.Parse(Console.ReadLine());
if( h < 0 ) Console.WriteLine("Please enter a positive number");
175 } while( h < 0 ); return h; } static void ProcessCylinder() { Console.WriteLine("Enter the dimensions of the cylinder"); Radius = GetRadius(); Height = GetHeight(); BaseArea = Radius * Radius * Math.PI; LateralArea = 2 * Math.PI * Radius * Height; TotalArea = 2 * Math.PI * Radius * (Height + Radius); Volume = Math.PI * Radius * Radius * Height; } static void ShowCylinder() { Console.WriteLine("\nCylinder Characteristics"); Console.WriteLine("Radius: {0}", Radius); Console.WriteLine("Height: {0}", Height); Console.WriteLine("Base: {0:F}", BaseArea); Console.WriteLine("Lateral: {0:F}", LateralArea); Console.WriteLine("Total: {0:F}", TotalArea); Console.WriteLine("Volume: {0:F}", Volume); } static void Main() { ProcessCylinder(); ShowCylinder(); } }
Console.WriteLine();
}
12. To execute the application, on the main menu, click Debug -> Start Without Debugging 13. Return to Visual C#
Introduction to Arguments Like a variable, an argument is represented by its type of value. For example, one method may need a character while another would need a string. Yet another method may require a decimal number. This means that the method or class that calls a method is responsible for supplying the right value, even though a method may have an internal mechanism of checking the validity of such a value. The value supplied to a method is typed in the parentheses of the method and it's called an argument. In order to declare a method that takes an argument, you must specify its name and the argument between its parentheses. Because a method must specify the type of value it would need, the argument is represented by its data type and a name. If the method would not return a value, it can be declared as void. Suppose you want to define a method that displays the side length of a square. Since you would
176
have to supply the length, you can define such a method as follows: using System; public class NewProject { void DisplaySide(double Length) { } static void Main() { } } In the body of the method, you may or may not use the value of the argument. Otherwise, you can manipulate the supplied value as you see fit. In this example, you can display the value of the argument as follows: using System; public class NewProject { void DisplaySide(double Length) { Console.Write("Length: "); Console.WriteLine(Length); } static void Main() { } } In this case, remember to define the method as static if you plan to access it from Main(). In order to call a method that takes an argument, you must supply a value for the argument when calling the method; otherwise you would receive an error. Also, you should/must supply the right value; otherwise, the method may not work as expected and produce an unreliable result. Here is an example: using System; public class NewProject { static void DisplaySide(double Length) { Console.Write("Length: "); Console.WriteLine(Length); } static void Main() { DisplaySide(35.55); }
Console.WriteLine();
} As mentioned already, a method that takes an argument can also declared its own variable. Such
177
variables are referred to as local. A method can take more than one argument. When defining such a method, provide each argument with its data type and a name. The arguments are separated by a comma.
Practical Learning: Passing Arguments 1. To pass arguments to a method, change the file as follows: using System; class Cylinder { static double GetTheRadius() { double rad; do { Console.Write("Radius: "); rad = double.Parse(Console.ReadLine()); if( rad < 0 ) Console.WriteLine("Please enter a positive number"); }
} while( rad < 0 ); return rad;
static double GetTheHeight() { double h; do {
number");
Console.Write("Height: "); h = double.Parse(Console.ReadLine()); if( h < 0 ) Console.WriteLine("Please enter a positive
} while( h < 0 ); }
return h;
static double CalculateBaseArea(double rad) { return rad * rad * Math.PI; } static double CalculateLateralArea(double rad, double hgt) { return 2 * Math.PI * rad * hgt; }
178 static double CalculateTotalArea(double rad, double hgt) { return 2 * Math.PI * rad * (hgt + rad); } static double CalculateVolume(double rad, double hgt) { return Math.PI * rad * rad * hgt; } static void ProcessCylinder() { double Radius; double Height; double BaseArea; double LateralArea; double TotalArea; double Volume; Console.WriteLine("Enter the dimensions of the cylinder"); Radius = GetTheRadius(); Height = GetTheHeight(); BaseArea LateralArea TotalArea Volume
= = = =
CalculateBaseArea(Radius); CalculateLateralArea(Radius, Height); CalculateTotalArea(Radius, Height); CalculateVolume(Radius, Height);
Console.WriteLine("\nCylinder Characteristics"); Console.WriteLine("Radius: {0}", Radius); Console.WriteLine("Height: {0}", Height); Console.WriteLine("Base: {0:F}", BaseArea); Console.WriteLine("Lateral: {0:F}", LateralArea); Console.WriteLine("Total: {0:F}", TotalArea); Console.WriteLine("Volume: {0:F}", Volume); } static void Main() { ProcessCylinder(); }
Console.WriteLine();
}
2. Execute the application Here is an example of executing the program: Enter the dimensions of the cylinder Radius: 35.96 Height: 30.28 Cylinder Radius: Height: Base:
Characteristics 35.96 30.28 4062.46
179 Lateral: 6841.56 Total: 14966.49 Volume: 123011.33 3. Return to Visual C#
Techniques of Passing Arguments Passing Arguments by Value When calling the methods that take one or more arguments, we made sure we provided the needed argument. This is because an argument is always required and the calling function or class must provided a valid value when calling such a method.
Practical Learning: Passing Arguments By Value 1. All the arguments we have used so far were passed by value. For one more example, change the program as follows: using System; class Cylinder { static double GetTheRadius() { double rad; do { Console.Write("Radius: "); rad = double.Parse(Console.ReadLine()); if( rad < 0 ) Console.WriteLine("Please enter a positive number"); }
} while( rad < 0 ); return rad;
static double GetTheHeight() { double h; do {
number");
Console.Write("Height: "); h = double.Parse(Console.ReadLine()); if( h < 0 ) Console.WriteLine("Please enter a positive
} while( h < 0 ); }
return h;
180
static double CalculateBaseArea(double rad) { return rad * rad * Math.PI; } static double CalculateLateralArea(double rad, double hgt) { return 2 * Math.PI * rad * hgt; } static double CalculateTotalArea(double rad, double hgt) { return 2 * Math.PI * rad * (hgt + rad); } static double CalculateVolume(double rad, double hgt) { return Math.PI * rad * rad * hgt; } static void ProcessCylinder() { double Radius; double Height; double BaseArea; double LateralArea; double TotalArea; double Volume; Console.WriteLine("Enter the dimensions of the cylinder"); Radius = GetTheRadius(); Height = GetTheHeight(); BaseArea LateralArea TotalArea Volume
= = = =
CalculateBaseArea(Radius); CalculateLateralArea(Radius, Height); CalculateTotalArea(Radius, Height); CalculateVolume(Radius, Height);
ShowCylinder(Radius, Height, BaseArea, LateralArea, TotalArea, Volume); }
vol)
static void ShowCylinder(double rad, double hgt, double BArea, double Lateral, double Total, double {
}
Console.WriteLine("\nCylinder Characteristics"); Console.WriteLine("Radius: {0}", rad); Console.WriteLine("Height: {0}", hgt); Console.WriteLine("Base: {0:F}", BArea); Console.WriteLine("Lateral: {0:F}", Lateral); Console.WriteLine("Total: {0:F}", Total); Console.WriteLine("Volume: {0:F}", vol);
181 static void Main() { ProcessCylinder(); }
Console.WriteLine();
} 2. Execute the application and test it. Here is an example: Enter the dimensions of the cylinder Radius: 38.26 Height: 28.48 Cylinder Radius: Height: Base: Lateral: Total: Volume:
Characteristics 38.26 28.48 4598.75 6846.44 16043.94 130972.40
3. Return to Visual C#
Passing an Argument by Reference Consider the following program: using System; public class Payroll { static void Earnings(double ThisWeek, double Salary) { ThisWeek = 42.50;
}
Console.WriteLine("\nIn the Earnings() function,"); Console.Write("Weekly Hours = "); Console.WriteLine(ThisWeek); Console.Write("Salary = "); Console.WriteLine(Salary); Console.Write("Weekly Salary: = "); Console.WriteLine(ThisWeek * Salary);
static void Main() { double Hours, Rate; Rate = 15.58; Hours = 26.00; Console.WriteLine("In the Main() function,"); Console.Write("\nWeekly Hours = "); Console.Write(Hours); Console.Write("\nSalary = "); Console.WriteLine(Rate);
182 Console.Write("Weekly Salary = "); Console.WriteLine(Hours * Rate); Console.WriteLine("\nCalling the Earnings() function"); Earnings(Hours, Rate); Console.Write("\nAfter calling the Earnings() function, "); Console.WriteLine("\nin the Main() function,"); Console.Write("\nWeekly Hours = "); Console.Write(Hours); Console.Write("\nSalary = "); Console.WriteLine(Rate); Console.Write("Weekly Salary = "); Console.WriteLine(Hours * Rate); }
Console.Write("\n");
}
Introduction to Classes A Re-Introduction to Classes Overview Based on a brief definition we had in the first lesson, we have been using classes in a very introductory manner. This was necessary because everything in C# is built around a concept of class. A class can be more elaborate than what we have been acquainted to. A class is a technique of creating one or a group of variables to be used as a foundation for a more detailed variable. A class must be created in a computer file. You can create such a file with only one class or you can create many classes inside of one file. To create a class, you start with the class keyword followed by a name and its body delimited by curly brackets. Here is an example of a class called Book: class Book { }
Practical Learning: Introducing Classes 1. Start Microsoft Visual C# or Visual Studio .NET 2. On the main menu, click File -> New -> Project 3. If necessary, in the Project Types list of the New Project dialog box, click Visual C# Projects
183 4. In the Templates list, click Empty Project 5. In the Name text box, replace the name with DeptStore1 and specify the desired path in the Location 6. Click OK 7. To create a source file for the project, on the main menu, click Project -> Add New Item... 8. In the Add New Item dialog box, in the Templates list, click Code File 9. In the Name text box, delete the suggested name and replace it with Exercise 10. Click Open 11. In the empty file, type the following: using System; class DepartmentStore { } class Exercise { static void Main() { } }
12. Save the file
Class Variable Declaration Like any normal variable, to use a class in your program, you can first declare a variable for it (when we study static fields, we will see that you can use a class without primarily declaring it). Like the variables we introduced in the previous lesson, to declare a variable of a class, type its name followed by a name for the variable. For example, to declare a variable of the above Book in another class called NewProject, you could type the following: using System; class Book { } class NewProject {
}
static void Main() { Book ToRead; } The variables we have declared so far are called value variables. This is because such a variable of a primitive type holds its value. The C# language supports another type of variable. This time, when you declare the variable, its name doesn't hold the value of the variable; it holds a
184
reference to the address where the actual variable is stored. This reference type is the kind used to declare a variable for a class. To use a variable as reference, you must initialize it using an operator called new. Here is an example: using System; class Book { } class NewProject { static void Main() { Book ToRead; ToRead = new Book(); }
} You can also use the new operator directly when declaring the variable as follows:
Book ToRead = new Book(); In C#, as well as Visual Basic, if you create a class in any of the files that belong to the same project, the class is made available to all other parts of the same project.
Practical Learning: Declaring a Class Variable 1. To use the DepartmentStore class in the main class of the project, declare the variable as follows: using System; class DepartmentStore { } class Exercise { static void Main() { DepartmentStore dptStore = new DepartmentStore(); } }
2. Save the exercise.cs file
Sharing Classes
185
Unlike its sisters the C and the C++ languages, C# was developed with the idea of working complementarily with other languages such as C++, Visual Basic, and J#. In other words, code from these other languages should be able to "read" or access code written in a C# application. To make this possible, a C# class can be created as a public object. If you want your class to be accessible to code written in other languages, precede the class keyword with public when creating it. Here is an example: using System; public class Exercise { static void Main() { int Number = 244; object Thing = 1450.58;
}
Console.WriteLine(Number); Console.WriteLine(Thing);
}
Garbage Collection When you initialize a variable using the new operator, you are in fact asking the compiler to provide you some memory space in the heap memory. The compiler is said to "allocate" memory for your variable. When that variable is no longer needed, such as when your program closes, it (the variable) must be removed from memory and the space it was using can be made available to other variables or other programs. This is referred to as garbage collection. In the past, namely in C/C++, this was a concern for programmers because they usually had to remember to manually delete such a variable (a pointer) and free its memory. The .NET Framework solves the problem of garbage collection by letting the compiler "clean" memory after you. This is done automatically when the compiler judges it necessary so that the programmer doesn't need to worry about this issue.
A Program With Various Files Instead of only one file, you can create a program with many of them. Each file can contain different assignments that, when put together, can create an application as complete as possible. To make this possible, you can create each file with a name and the extension .cs. To compile the project, after typing csc, you can list the files separated by commas.
In C++ and Pascal, if you create a class CA in a certain file FA and want to access anything included in that class from another file FB, you must type #include (C/C++) or uses (Pascal) followed by the name of the file FA somewhere in the top section of the file FB.
Class' Fields Introduction Consider the Book class defined earlier:
186 public class Book { } The section between the curly brackets of a class is referred to as its body. In the body of a class, you can create a list of the parts that make up the class. Each of these parts must be a complete variable with a name and a data type. For example, here are the characteristics that make up a book, declared as the parts of the above Book class and each declared as a variable: public class Book { string Title; string Author; short YearPublished; int NumberOfPages; char CoverType; } The variables declared in the body of a class are referred to as its member variables and each member variable is referred to as a field. The fields can be any type we have seen in the previous lesson. Based on this, when creating a class, it is your job to decide what your object is made of.
Practical Learning: Introducing Class Members Imagine you want to write a (console-based) program for a department store and the customer has given you a preliminary catalog as follows:
Stock #: 437876 Women Spring Coat Classy Unit: $145.55
Stock #: 79475 Women Bathing Suit Sandstone $75.55
Stock #: 74797 Women Suit Exchange $225.75
187
Stock: 68432 Men Jacket $115.85
Stock #: 75947 Children Summer Hat $17.95
Stock #: 48746 Children Playground Dress $24.55
Each item in this catalog is represented by its Stock number, its name or description, and its price. Based on this, you can create a class that represents each item.
1. Change the DepartmentStore class as follows: using System; public class DepartmentStore { long ItemNumber; string ItemName; double UnitPrice; } public class Exercise { static void Main() { DepartmentStore dptStore = new DepartmentStore(); } }
2. Save the file
Access to Class Members The parts of an object fall into two main categories: those you can touch and those you don't have access to. For example, for a car parked at the mall, you can see or touch its doors and its tires but you don't see its engine or its spare tire, you don't even know if it has one. The parts of an object that you have access to are referred to as public. Those you can't see or
188
touch are referred to as private. A C# class also recognizes that some parts of a class can be made available to other classes and some other parts can be hidden from other classes. A part that must be hidden from other classes is private and it can be declared starting with the private keyword. If you declare a member variable and want to make it available to other classes, you must start its name with the public keyword. The public and private keywords are referred to as access level. By default, if you declare a member variable (or anything else) in a class but don't specify its access level, the member is considered private and cannot be accessed from outside, that is by a non-member, of that class. Therefore, to make a member accessible by other classes, you must declare it as public. You can use a mix of public and private members in a class and there is no rule on which access level should be listed first or last. Here is an example: public class Book { public string Title; public string Author"; short YearPublished; private int NumberOfPages; char CoverType; } Just keep in mind that if you omit or forget the access level of a member of a class, the member is automatically made private. After declaring a member of a class, to access it from another class, first declare a variable from its class as we saw earlier. To actually access the method, use the period operator as follows: using System; class Book { public string Title; public string Author; short YearPublished; private int NumberOfPages; char CoverType; } class BookClub { static void Main() { Book ToRead = new Book(); ToRead.Author = "Francis Patrick Kouma"; }
Console.WriteLine(ToRead.Author);
} To reduce confusion as to what member is public or private, we will always specify the access
189
level of a member variable.
Practical Learning: Using a Class' Fields 1. To make public the members of the DepartmentStore class, type the public keyword to their left 2. To access the members of the DepartmentStore class, change Main() as follows: using System; public class DepartmentStore { public long ItemNumber; public string ItemName; public double UnitPrice; } public class Exercise { static void Main() { DepartmentStore dptStore = new DepartmentStore(); dptStore.ItemNumber = 846785; dptStore.ItemName = "Women Underwear"; dptStore.UnitPrice = 15.65; Console.WriteLine("Department Store"); Console.WriteLine("Item #: {0}", dptStore.ItemNumber); Console.WriteLine("Description: {0}", dptStore.ItemName); Console.WriteLine("Unit Price: {0:C}\n", dptStore.UnitPrice); } }
3. Execute the application 4. Return to Visual C#
Characteristics of Members of a Class Constants Unlike C/C++, in C#, you can create a constant variable in a class. As done in Lesson 2 when studying variables, to declare a constant variable, type the const keyword to the left of the variable. Once again, when declaring a constant, you must initialize it with an appropriate
190
constant value. Here is an example: using System; public class Exercise { public static void MeterToInch() { const double ConversionFactor = 39.37; double Meter, Inch; string Answer; do {
Console.Write("Enter the value in meters: Meter = double.Parse(Console.ReadLine());
");
Inch = Meter * ConversionFactor; Console.WriteLine("{0}m = {1}in", Meter, Inch); Console.Write("\nDo you want to perform another conversions(y/n)? ");
Answer = Console.ReadLine(); Console.WriteLine(); } while(Answer == "y" || Answer == "Y");
} static void Main() { MeterToInch(); } } Here is an example of running the program: Enter the value in meters: 25.38 25.38m = 999.2106in Do you want to perform another conversions(y/n)? y Enter the value in meters: 44.68 44.68m = 1759.0516in Do you want to perform another conversions(y/n)? Y Enter the value in meters: 18.28 18.28m = 719.6836in Do you want to perform another conversions(y/n)? n
Practical Learning: Creating a Constant 1. To start a new project, on the main menu, click File -> New -> Project 2. In the Templates section, click Empty Project
191 3. Set the Name to IceCream1 and press Enter 4. To add a source file, on the main menu, click Project -> Add New Item... 5. In addition to what we have learned so far, to create two constants, type the following: using System; class IceCream { public const decimal BasePrice = 1.05M; public const string DefaultFlavor = "Diet Mint Fudge High Carb"; public public public public public
char Flavor; char Container; char Ingredient; int Scoops; decimal TotalPrice;
} class Exercise { static void Main() { } }
6. 7. 8. 9.
Save the file in a new folder named IceCream1 Save the file itself as Exercise.cs At the Command Prompt, switch to the IceCream1 directory Compile and test the file then return to Notepad
Read-Only Fields When creating a member variable of a class, one of the decisions you make consists of deciding how the field would get its value(s). Sometimes you will allow the clients of the class to change the values of the field. In some other cases, you may want the field to only hold or present the value without being able to change it. This can still allow the clients to access the field and its value but on a read-only basis. To create a field whose value can only be read, precede its data type, during declaration, with the readonly keyword. Here is an example: public readonly double PI; After declaring the variable, you should initialize it. You have two main alternatives. You can initialize the field when declaring it. Here is an example: using System; namespace Geometry {
192 class Circle { public double Radius; public Circle(double rad) { Radius = rad; } }
public readonly double PI = 3.14159;
class Exercise { static int Main() { Circle circ = new Circle(24.72); Console.WriteLine("Circle Characteristics"); Console.WriteLine("Radius: {0}", circ.Radius); Console.WriteLine("PI: {0}\n", circ.PI); return 0; }
}
} Alternatively, you can initialize the field in the(a) constructor of its class. This would be done as follows: using System; namespace Geometry { class Circle { public double Radius; public Circle(double rad) { Radius = rad; PI = 3.14159; } public readonly double PI; } class Exercise { static int Main() { Circle circ = new Circle(24.72); Console.WriteLine("Circle Characteristics"); Console.WriteLine("Radius: {0}", circ.Radius); Console.WriteLine("PI: {0}\n", circ.PI);
193 return 0; }
}
} If the value held by a read-only field is gotten from an expression, then the field must be initialized in the(a) construction with the desired expression. Based on this, the following code will not compile: using System; namespace Geometry { class Circle { public double Radius; public Circle(double rad) { Radius = rad; PI = 3.14159; } public readonly double PI; public readonly double Diameter = Radius * 2; } class Exercise { static int Main() { Circle circ = new Circle(24.72); Console.WriteLine("Circle Characteristics"); Console.WriteLine("Radius: {0}", circ.Radius); Console.WriteLine("PI: {0}\n", circ.PI); Console.WriteLine("Diameter: {0}\n", circ.Diameter); return 0; }
}
} This would produce: C:\Programs\MSVCS\Project1\Exercise.cs(16): A field initializer cannot reference the nonstatic field, method, or property 'Geometry.Circle.Radius' One solution to this error is to declare the field as read-only in the class and then initialize it in the(a) constructor with the expression. Here are a few examples: using System; namespace Geometry { class Circle {
194 public double Radius; public Circle(double rad) { Radius = rad; Diameter = Radius * 2; Circumference = Diameter * PI; Area = Radius * Radius * PI; }
}
public public public public
readonly readonly readonly readonly
double double double double
PI = 3.14159; Diameter; Circumference; Area;
class Exercise { static int Main() { Circle circ = new Circle(24.72);
circ.Circumference);
Console.WriteLine("Circle Characteristics"); Console.WriteLine("Radius: {0}", circ.Radius); Console.WriteLine("Diameter: {0}", circ.Diameter); Console.WriteLine("Circumference: {0}", Console.WriteLine("Area:
} }
{0}\n", circ.Area);
return 0;
} This would produce:
Circle Characteristics Radius: 24.72 Diameter: 49.44 Circumference: 155.3202096 Area: 1919.757790656 In the previous section, we saw that a constant variable must be initialized when it is created. Although a read-only variable seems to follow the same rule, it doesn't. Remember that you don't need to initialize a read-only variable when you declare it since you can do this in the(a) constructor of the class. Also, because a constructor can be overloaded, a read-only field can hold different values depending on the particular constructor that is accessed at a particular time but the value of a constant variable cannot change: it is initialized once, in the class (or in a method) and it keeps that value throughout the class (or method).
Static Fields Imagine you create a class called Book. To access it in the Main() function, you can declare its variable, as we have done so far. A variable you have declared of a class is also called an instance of the class. In the same way, you can declare various instances of the same class as
195
necessary: using System; public class Book { public string public string public short public int public char }
Title; Author"; YearPublished; NumberOfPages; CoverType;
public class NewProject { static void Main() { Book written = new Book(); Book bought = new Book(); } } Each one of these instances gives you access to the members of the class but each instance holds the particular values of the members of its instance. Consider the results of the following program: using System; public class Book { public string public string public short public int public char }
Title; Author; YearPublished; NumberOfPages; CoverType;
public class Program { static void Main() { Book First = new Book(); First.Title First.Author First.YearPublished First.NumberOfPages First.CoverType
= = = = =
"Psychology and Human Evolution"; "Jeannot Lamm"; 1996; 872; 'H';
Console.WriteLine("Book Characteristics"); Console.WriteLine("Title: {0}", First.Title); Console.WriteLine("Author: {0}", First.Author); Console.WriteLine("Year: {0}", First.YearPublished); Console.WriteLine("Pages: {0}", First.NumberOfPages); Console.WriteLine("Cover: {0}\n", First.CoverType);
196 Book Second = new Book(); Second.Title = "C# First Step"; Second.Author = "Alexandra Nyango"; Second.YearPublished = 2004; Second.NumberOfPages = 604; Second.CoverType = 'P';
}
Console.WriteLine("Book Characteristics"); Console.WriteLine("Title: {0}", Second.Title); Console.WriteLine("Author: {0}", Second.Author); Console.WriteLine("Year: {0}", Second.YearPublished); Console.WriteLine("Pages: {0}", Second.NumberOfPages); Console.WriteLine("Cover: {0}\n", Second.CoverType);
} This would produce: Book Characteristics Title: Psychology and Human Evolution Author: Jeannot Lamm Year: 1996 Pages: 872 Cover: H Book Characteristics Title: C# First Step Author: Alexandra Nyango Year: 2004 Pages: 604 Cover: P All of the member variables and methods of classes we have used so far are referred to as instance members because, in order to access them, you must have an instance of a class declared in another class in which you want to access them. C# allows you to declare a class member and refer to it regardless of which instance of an object you are using. Such a member variable is called static. To declare a member variable of a class as static, type the static keyword on its left. Whenever you have a static member, in order to refer to it, you must "qualify" it in the class in which you want to call it. Qualifying a member means you must give its complete location, including the name of its class and the namespace (if any) in which its class was created. Here is an example: using System; public class Book { public static string Title; public static string Author; public short YearPublished; public int NumberOfPages; public char CoverType; } public class Program {
197 static void Main() { Book First = new Book(); Book.Title = "Psychology and Human Evolution"; Book.Author = "Jeannot Lamm"; First.YearPublished = 1996; First.NumberOfPages = 872; First.CoverType = 'H'; Console.WriteLine("Book Characteristics"); Console.WriteLine("Title: {0}", Book.Title); Console.WriteLine("Author: {0}", Book.Author); Console.WriteLine("Year: {0}", First.YearPublished); Console.WriteLine("Pages: {0}", First.NumberOfPages); Console.WriteLine("Cover: {0}\n", First.CoverType); Book Second = new Book(); Book.Title = "C# First Step"; Book.Author = "Alexandra Nyango"; Second.YearPublished = 2004; Second.NumberOfPages = 604; Second.CoverType = 'P'; Console.WriteLine("Book Characteristics"); Console.WriteLine("Title: {0}", Book.Title); Console.WriteLine("Author: {0}", Book.Author); Console.WriteLine("Year: {0}", Second.YearPublished); Console.WriteLine("Pages: {0}", Second.NumberOfPages); Console.WriteLine("Cover: {0}\n", Second.CoverType); Console.ReadLine(); }
} Notice that when a member variable has been declared as static, you don't need an instance of the class to access that member variable outside of the class. Based on this, if you declare all members of a class as static, you don't need to declare a variable of their class in order to access them. In the following example, the Title and Author fields of the Book class are accessed from the Program class without using an instance of the Book class:
using System; public class Book { public static string Title; public static string Author; } public class Program { static void Main() { Book.Title = "Psychology and Human Evolution"; Book.Author = "Jeannot Lamm";
198 Console.WriteLine("Book Characteristics"); Console.WriteLine("Title: {0}", Book.Title); Console.WriteLine("Author: {0}\n", Book.Author); Book.Title = "C# First Step"; Book.Author = "Alexandra Nyango"; Console.WriteLine("Book Characteristics"); Console.WriteLine("Title: {0}", Book.Title); Console.WriteLine("Author: {0}\n", Book.Author); }
Console.ReadLine();
} As we saw in Lesson 6, you can also declare member variables of the main class as static. If you are referring to a static member variable in the same class in which it was declared, you don't have to qualify it. Here is an example: using System; public class NewProject { static double Length; static double Width; static void Main() { Console.WriteLine("Rectangles Characteristics"); Length = 22.55; Width = 20.25; Console.WriteLine("\nRectangle 1"); Console.Write("Length: "); Console.WriteLine(Length); Console.Write("Width: "); Console.WriteLine(Width); Length = 254.04; Width = 408.62; Console.WriteLine("\nRectangle 2"); Console.Write("Length: "); Console.WriteLine(Length); Console.Write("Width: "); Console.WriteLine(Width); }
Console.WriteLine();
}
Practical Learning: Using Static Fields 1. To use static fields, change the program as follows:
199 using System; class IceCream { public const decimal BasePrice = 1.05M; public const string DefaultFlavor = "Diet Mint Fudge High Carb";
}
public public public public public
static static static static static
char Flavor; char Container; char Ingredient; int Scoops; decimal TotalPrice;
class Exercise { static void Main() { Console.WriteLine("Ice Cream Vendor Machine"); Console.WriteLine("What type of flavor do you want?"); Console.WriteLine("a - French Vanilla"); Console.WriteLine("b - Strawberry Vanilla"); Console.WriteLine("c - Butter Pecan"); Console.WriteLine("d - Cream of Cocoa"); Console.Write("Your Choice? " ); IceCream.Flavor = char.Parse(Console.ReadLine()); Console.WriteLine("What type of container do you want?"); Console.WriteLine("1 - Cone\n2 - Cup\n3 - Bowl"); Console.Write("Your Choice? "); IceCream.Container = char.Parse(Console.ReadLine()); Console.WriteLine("Do you want an ingredient or not"); Console.WriteLine("0 - No Ingredient"); Console.WriteLine("1 - Peanuts"); Console.WriteLine("2 - M & M"); Console.WriteLine("3 - Cookies"); Console.Write("Your Choice? "); IceCream.Ingredient = char.Parse(Console.ReadLine()); Console.Write("How many scoops(1, 2, or 3)? "); IceCream.Scoops = int.Parse(Console.ReadLine()); IceCream.TotalPrice = IceCream.BasePrice * IceCream.Scoops; Console.WriteLine("\nIce Cream Order"); switch(IceCream.Flavor) { case 'a': case 'A': Console.WriteLine("Flavor: break; case 'b': case 'B': Console.WriteLine("Flavor: break;
French Vavilla");
Strawberry Vanilla");
200 case 'c': case 'C': Console.WriteLine("Flavor: Butter Pecan"); break; case 'd': case 'D': Console.WriteLine("Flavor: Cream of Cocoa"); break; default: Console.WriteLine("Confused Flavor - {0}", IceCream.DefaultFlavor); break; } switch(IceCream.Container) { case '1': Console.WriteLine("Container: break; case '2': Console.WriteLine("Container: break; case '3': Console.WriteLine("Container: break; default: Console.WriteLine("Container: break; } switch(IceCream.Ingredient) { case '0': Console.WriteLine("Ingredient: break; case '1': Console.WriteLine("Ingredient: break; case '2': Console.WriteLine("Ingredient: break; case '3': Console.WriteLine("Ingredient: break; default: Console.WriteLine("Ingredient: break; }
}
Cone"); Cup"); Bowl"); Cone");
None"); Peanuts"); M & M"); Cookies"); None");
Console.WriteLine("Scoops: {0}", IceCream.Scoops); Console.WriteLine("Total Price: {0:C}", IceCream.TotalPrice); Console.WriteLine();
}
2. Save the file, compile and test it at the Command Prompt. Here is an example:
201 3. Return to Notepad
Static Methods Like a member variable, a method of a class can be define as static. This means that this particular method can access any member of the class regardless of the instance if there are many instances of the class declared. To define a method as static, type the static keyword to its left. Here is an example: using System; public class Book { private static static private private static static private
string string int double
Title; Author; Pages; Price;
static public void CreateBook() { Title = "Psychology and Human Evolution"; Author = "Jeannot Lamm"; Pages = 472; Price = 24.95; }
}
static public void ShowBook() { Console.WriteLine("Book Characteristics"); Console.WriteLine("Title: {0}", Book.Title); Console.WriteLine("Author: {0}", Book.Author); Console.WriteLine("Pages: {0}", Pages); Console.WriteLine("Price: {0:C}\n", Price); }
public class Program { static void Main() { Book.CreateBook(); Book.ShowBook(); } } This would produce: Book Characteristics Title: Psychology and Human Evolution Author: Jeannot Lamm Pages: 472 Price: $24.95 The ReadLine(), the Write(), and the WriteLine() methods of the Console class that we have used so far are examples of static methods. There are many others in the C# language.
202
The documentation can guide you to know what method of what class is static or not.
Practical Learning: Using Static Methods 1. To use static methods, change the file as follows: using System; class IceCream { public const decimal BasePrice = 1.05M; public const string DefaultFlavor = "Diet Mint Fudge High Carb"; private private private private private
static static static static static
char Flavor; char Container; char Ingredient; int Scoops; decimal TotalPrice;
public static void ProcessAnOrder() { Console.WriteLine("Ice Cream Vendor Machine"); Console.WriteLine("What type of flavor do you want?"); Console.WriteLine("a - French Vanilla"); Console.WriteLine("b - Strawberry Vanilla"); Console.WriteLine("c - Butter Pecan"); Console.WriteLine("d - Cream of Cocoa"); Console.Write("Your Choice? " ); IceCream.Flavor = char.Parse(Console.ReadLine()); Console.WriteLine("What type of container do you want?"); Console.WriteLine("1 - Cone\n2 - Cup\n3 - Bowl"); Console.Write("Your Choice? "); IceCream.Container = char.Parse(Console.ReadLine()); Console.WriteLine("Do you want an ingredient or not"); Console.WriteLine("0 - No Ingredient"); Console.WriteLine("1 - Peanuts"); Console.WriteLine("2 - M & M"); Console.WriteLine("3 - Cookies"); Console.Write("Your Choice? "); IceCream.Ingredient = char.Parse(Console.ReadLine()); Console.Write("How many scoops(1, 2, or 3)? "); IceCream.Scoops = int.Parse(Console.ReadLine()); IceCream.TotalPrice = IceCream.BasePrice * IceCream.Scoops; } public static void DisplayReceipt() { Console.WriteLine("\nIce Cream Order"); switch(IceCream.Flavor)
203 { case 'a': case 'A': Console.WriteLine("Flavor: French Vavilla"); break; case 'b': case 'B': Console.WriteLine("Flavor: Strawberry Vanilla"); break; case 'c': case 'C': Console.WriteLine("Flavor: Butter Pecan"); break; case 'd': case 'D': Console.WriteLine("Flavor: Cream of Cocoa"); break; default: Console.WriteLine("Confused Flavor - {0}", IceCream.DefaultFlavor); break; } switch(IceCream.Container) { case '1': Console.WriteLine("Container: break; case '2': Console.WriteLine("Container: break; case '3': Console.WriteLine("Container: break; default: Console.WriteLine("Container: break; } switch(IceCream.Ingredient) { case '0': Console.WriteLine("Ingredient: break; case '1': Console.WriteLine("Ingredient: break; case '2': Console.WriteLine("Ingredient: break; case '3': Console.WriteLine("Ingredient: break; default: Console.WriteLine("Ingredient: break;
Cone"); Cup"); Bowl"); Cone");
None"); Peanuts"); M & M"); Cookies"); None");
204 } Console.WriteLine("Scoops: {0}", IceCream.Scoops); Console.WriteLine("Total Price: {0:C}", IceCream.TotalPrice);
} }
class Exercise { static void Main() { IceCream.ProcessAnOrder(); IceCream.DisplayReceipt(); Console.WriteLine(); }
}
2. Save, compile, and test the file 3. Return to Notepad
this Instance We have mentioned two techniques of accessing the members of a class, one consisted of declaring a variable of the class, the other had to do with static members. None of these techniques is important if you want to access a field or method of a class from another method of the same class. We know already that the members of a class are made available to all other members of the same class without being declared or qualified. Consider the following class: class Triangle { double Base; double Height; double Area; void Show() { double Area; Area = Base * Height / 2; }
} When the Area variable is used in the Show() method, there are two variables available and named Area. It makes it confusing to know what particular variable is being accessed. C#, like many other languages, provides a special member of a class that allows you to specify the member of a class when accessing it. This member is called this. When using the this member variable (in C/C++, it is a pointer), you can access any member of a class within any method of the same class. Here is an example:
using System; class Triangle
205 { double Base; double Height; public void Show() { double Area; // Using "this" to access the members of this class this.Base = 24.55; this.Height = 20.75; // You cannot use this to access Area because Area // is not a member of this class Area = this.Base * this.Height / 2;
}
Console.WriteLine("Triangle Characteristics"); Console.WriteLine("Base: {0}", this.Base); Console.WriteLine("Height: {0}", this.Height); Console.WriteLine("Area: {0}", Area);
} class Exercise { static void Main() { Triangle tri = new Triangle(); tri.Show(); } } This would produce: Triangle Characteristics Base: 24.55 Height: 20.75 Area: 254.70625 There are exceptions when using this: • •
The this member can never be declared: it is automatically implied when you create a class this cannot be used in a class A to access a member of class B. The following will cause an error: class Exercise { static void Main() { Triangle tri = new Triangle(); this.tri.Show(); } }
206
•
this cannot be used in a static method. The following program will not compile because this is used in the Show() method declared as a static method: using System; class Triangle { static double Base; static double Height; static public void Show() { double Area; // Using "this" to access the members of this class this.Base = 24.55; this.Height = 20.75; // You cannot use this to access Area because Area // is not a member of this class Area = this.Base * this.Height / 2;
}
Console.WriteLine("Triangle Characteristics"); Console.WriteLine("Base: {0}", this.Base); Console.WriteLine("Height: {0}", this.Height); Console.WriteLine("Area: {0}", this.Area);
} class Exercise { static void Main() { Triangle.Show(); } }
Practical Learning: Using this 1. To start a new file, on the main menu of Notepad, click File -> New 2. In addition to what we have learned so far, to use this, type the following: using System; public class StoreItem { private long ItemNumber; private string ItemName; private double UnitPrice;
207 public void CreateAnItem(long nbr, string name, double price) { this.ItemNumber = nbr; this.ItemName = name; this.UnitPrice = price; }
}
public void DisplayAnItem() { Console.WriteLine("Department Store"); Console.WriteLine("Item #: {0}", this.ItemNumber); Console.WriteLine("Description: {0}", this.ItemName); Console.WriteLine("Unit Price: {0:C}\n", this.UnitPrice); }
public class Exercise { static void Main() { StoreItem item = new StoreItem();
}
item.CreateAnItem(348649, "Men 3-Piece Jacket", 275.95); item.DisplayAnItem();
}
3. Save the file in a new folder named DeptStore2 4. Save the file itself as Exercise.cs 5. Compile it at the Command Prompt and test it. This would produce: Department Store Item #: 348649 Description: Men 3-Piece Jacket Unit Price: $275.95
6. Return to Notepad
Structures Introduction A structure is an enhanced version of the primitive data types we have used in previous lessons. The difference is that, like a class, a structure is created from one primitive type or by combining various primitive types, resulting in an advanced data type that is not inherently built in the C# language. To create a structure, you use the same formula as a class but with the struct keyword. Here
208
is an example of a structure: struct Box { } Like a class, a structure can have fields. They are listed in the body of the structure.
Practical Learning: Creating a Structure 1. To create a structure, change the file as follows: using System; public struct StoreItem { public long ItemNumber; public string ItemName; public double UnitPrice; public void DisplayAnItem() { Console.WriteLine("Department Store"); Console.WriteLine("Item #: {0}", this.ItemNumber); Console.WriteLine("Description: {0}", this.ItemName); Console.WriteLine("Unit Price: {0:C}\n", this.UnitPrice); } } public class Exercise { static void Main() { }
}
2. Save the Exercise.cs file
Structure Declaration Like any other data type, to use a structure, you can first declare a variable from it. Like primitive data types and unlike a class, a structure is a value type. Therefore, you can declare it without the new keyword. Here is an example: using System; struct Box
209 { } class DeptStore { static void Main() { Box boite; } } Like the primitive data type, the memory for a variable of a structure is allocated on the stack but you can use the new operator to declare a structure: using System; struct Box { } class DeptStore { static void Main() { Box boite = new Box(); Console.WriteLine(); }
} Although there are many similarities in the behaviors of classes and structures, you should use a structure when the object you are creating is meant to represent relatively small values.
Practical Learning: Declaring a Structure 1. To declare and initialize a variable of a structure, change the file as follows: using System; public struct StoreItem { public long ItemNumber; public string ItemName; public double UnitPrice; public void DisplayAnItem() { Console.WriteLine("Department Store"); Console.WriteLine("Item #: {0}", this.ItemNumber); Console.WriteLine("Description: {0}", this.ItemName); Console.WriteLine("Unit Price: {0:C}\n", this.UnitPrice); }
210 } public class Exercise { static void Main() { StoreItem item; item.ItemNumber = 348649; item.ItemName = "Men 3-Piece Jacket"; item.UnitPrice = 275.95; }
item.DisplayAnItem();
}
2. Save the Exercise.cs file 3. Compile and execute it
Class Construction and Destruction The Default Constructor When you declare a variable of a class, a special method must be called to initialize the members of that class. This method is automatically provided for every class and it is called a constructor. Whenever you create a new class, a constructor is automatically provided to it. This particular constructor is called the default constructor. You have the option of creating it or not. Although a constructor is created for your class, you can customize its behavior or change it tremendously. A constructor holds the same name as its class and doesn't return any value, not even void. Here is an example: public class Book { Book() } Like every method, a constructor can be equipped with a body. In this body, you can access any of the member variables (or method(s)) of the same class. When introducing classes other than the main class, we saw that, to use such a class, you can declare its variable and allocate memory using the new operator. You can notice that we always included the parentheses when declaring such a variable. Here is an example: public class Class1 { static void Main() { Exercise exo = new Exercise(); } } In this case, the parentheses indicate that we are calling the default constructor to instantiate
211
the class.
C++ Note In C++, if you declare a class variable without having to initialize it, you can omit the parentheses. Consider the following program: using System; public class Exercise { public void Welcome() { Console.WriteLine("The wonderful world of C# programming"); }
}
public Exercise() { Console.WriteLine("The Exercise class is now available"); }
public class Class1 { static void Main() { Exercise exo = new Exercise(); } } When executed, it would produce: The Exercise class is now available This shows that, when a class has been instantiated, its constructor is the first method to be called. For this reason, you can use a constructor to initialize a class, that is, to assign default values to its member variables. When a constructor is used to initialize a variable declared for a class. That constructor is referred to as an instance constructor.
Practical Learning: Constructing a Class 1. Start a new file in Notepad and, in the empty file, type the following: using System; public class Applicant { public string FullName; public string Address; public string City; public string State;
212 public public public public public public
}
string string string int string int
ZIPCode; Sex; DateOfBirth; Weight; Height; Race;
public Applicant() { this.FullName = "Unknown"; this.Sex = "Ungenerated"; }
public class Exercise { public static int Main() { Applicant App = new Applicant(); Console.WriteLine("\n -=- Motor Vehicle Administration -=-"); Console.WriteLine(" --- Driver's License Information ---"); Console.WriteLine("Full Name: {0}", App.FullName); Console.WriteLine("Sex: {0}\n", App.Sex); }
return 0;
}
2. Save the file in a new folder named MVA1 3. Save the file itself as Exercise.cs 4. Switch to the Command Prompt and change the directory to the MVA1 folder that contains the current file 5. Compile the program at the Command Prompt with csc Exercise.cs and execute it with Exercise. This would produce: -=- Motor Vehicle Administration -=--- Driver's License Information --Full Name: Unknown Sex: Ungenerated
6. Return to Notepad
A Constructor With Argument In the previous section, we saw that there is always a default constructor for a new class that you create; you just the option of explicitly creating one or not. The default constructor as we
213
saw it doesn't take arguments: this is not a rule, it is simply assumed. Instead of a default constructor, you may want to create a constructor that takes an argument. Here is an example: public class Quadrilateral { public Quadrilateral(double side) { } } With this type of constructor, when you declare an instance of the class, you can use this new constructor to initialize the class. Here is an example: using System; public class Quadrilateral { public Quadrilateral(double side) { }
}
public class Class1 { static void Main() { Quadrilateral Square = new Quadrilateral(6.55); } } If you create one constructor for your class and pass at least one argument to that constructor, the automatic default constructor created by the compiler disappears. This implies that if you declare an instance of the class and use the default constructor to initialize it, you would receive an error when you compiler the program. Based on this rule, the following program will not compile: using System; public class Quadrilateral { public Quadrilateral(double side) { }
}
public class Class1 { static void Main() { Quadrilateral Square = new Quadrilateral(); } }
214
If you still want to use the default constructor in a class after creating a constructor that takes at least one argument, you must explicitly create that default constructor.
Practical Learning: Constructing a Class 1. To pass an argument to a constructor, change the file as follows: using System; public class Applicant { public string FullName; public string Address; public string City; public string State; public string ZIPCode; public string Sex; public string DateOfBirth; public int Weight; public string Height; public int Race;
}
public Applicant(string n) { this.FullName = n; }
public class Exercise { static Applicant RegisterPersonalInformation() { string name; char sex; string gender = null; Console.WriteLine("Applicant's Registration"); Console.Write("Full Name: "); name = Console.ReadLine(); do {
(sex != 'M') ) character"); (sex != 'M') );
Console.Write("Sex(F=Female/M=Male): "); sex = char.Parse(Console.ReadLine()); if( (sex != 'f') && (sex != 'F') && (sex != 'm') && Console.WriteLine("Please enter a valid
}while( (sex != 'f') && (sex != 'F') && (sex != 'm') &&
215
if( (sex == 'f') gender = else if( (sex == gender =
|| sex == 'F' ) "Female"; 'm') || (sex == 'M') ) "Male";
Applicant person = new Applicant(name); person.Sex = gender; }
return person;
public static int Main() { Console.WriteLine(" -=- Motor Vehicle Administration -=-"); Console.WriteLine(" --- Driver's License Application ---"); Applicant App = RegisterPersonalInformation(); Console.WriteLine("\n -=- Motor Vehicle Administration
-=-");
Console.WriteLine(" --- Driver's License Information ---"); Console.WriteLine("Full Name: Console.WriteLine("Sex:
{0}", App.FullName); {0}\n", App.Sex);
return 0; }
}
2. Save, compile, and execute the program. Here is an example: -=- Motor Vehicle Administration -=--- Driver's License Application --Applicant's Registration Full Name: Ernestine Koullah Sex(F=Female/M=Male): G Please enter a valid character Sex(F=Female/M=Male): F -=- Motor Vehicle Administration -=--- Driver's License Information --Full Name: Ernestine Koullah Sex: Female
3. Return to Notepad
Static Constructors Like the above described instance constructors, a static constructor is used to initialize a class. The main difference is that a static constructor works internally, in the class. Therefore, it is not used to initialize a variable of the class and you can never declare a variable of a class using a static constructor.
216
To make a constructor static, when creating it, type the static keyword to its left. Here is an example: using System; public class Quadrilateral { static Quadrilateral() { }
}
public class Class1 { static void Main() { // Use the default constructor to initialize an instance of the class Quadrilateral Square = new Quadrilateral(); } } In the above class, a static constructor is created for the class but the default constructor is still available and it is used to instantiate the class.
Constructor Overloading A constructor is the primary method of a class. It allows the programmer to initialize a variable of a class when the class is instantiated. A constructor that plays this role of initializing an instance of a class is also called an instance constructor. Most of the time, you don't even need to create a constructor, since one is automatically provided to any class you create. Sometimes too, as we have seen in some classes, you need to create your own class as you judge it necessary. And sometimes, a single constructor may not be sufficient. For example, when creating a class, you may decide, or find out, that there must be more than one way for a user to initialize a variable. Like and also or a
any other method, a constructor can be overloaded. In other words, you can create a class give it more than one constructor. The same rules used on overloading regular methods apply to constructors: the different constructors must have different number of arguments different number of arguments.
Practical Learning: Overloading a Constructor 1. To overload the constructor, change the file as follows: using System; public class Applicant { public string FullName;
217 public public public public public public public public public
string string string string string string int string int
Address; City; State; ZIPCode; Sex; DateOfBirth; Weight; Height; Race;
// The default constructor, used to initialize an // Applicant instance without much information public Applicant() { this.FullName = "Unknown"; this.Sex = "Ungenerated"; } // A constructor that is passed only one argument public Applicant(string n) { this.FullName = n; } // A constructor with more than one argument // This type is suitable to completely initialize a variable public Applicant(string n, string s, string dob) { this.FullName = n; this.Sex = s; this.DateOfBirth = dob; } } public class Exercise { static Applicant RegisterPersonalInformation() { string name; char sex; string gender = null; string dob; Console.WriteLine(" -=- Motor Vehicle Administration -=-"); Console.WriteLine("Applicant's Registration"); Console.Write("Full Name: "); name = Console.ReadLine(); do {
(sex != 'M') )
Console.Write("Sex(F=Female/M=Male): "); sex = char.Parse(Console.ReadLine()); if( (sex != 'f') && (sex != 'F') && (sex != 'm') &&
218 Console.WriteLine("Please enter a valid
character"); (sex != 'M') );
}while( (sex != 'f') && (sex != 'F') && (sex != 'm') && if( (sex == 'f') gender = else if( (sex == gender =
|| sex == 'F' ) "Female"; 'm') || (sex == 'M') ) "Male";
Console.Write("Date of Birth(mm/dd/yyyy): "); dob = Console.ReadLine(); Applicant person = new Applicant(name, gender, dob); return person; }
-=-");
static void Show(Applicant person) { Console.WriteLine("\n -=- Motor Vehicle Administration Console.WriteLine(" --- Applicant's Personal Information
---");
Console.WriteLine("Full Name: {0}", person.FullName); Console.WriteLine("Sex: {0}", person.Sex); Console.WriteLine("Date of Birth: {0}\n", person.DateOfBirth); } public static int Main() { Applicant App = new Applicant(); App = RegisterPersonalInformation(); Show(App); return 0; }
}
2. Save, compile, and test the file. Here is an example: -=- Motor Vehicle Administration -=Applicant's Registration Full Name: Dominique Monay Sex(F=Female/M=Male): d Please enter a valid character Sex(F=Female/M=Male): M Date of Birth(mm/dd/yyyy): 06/10/1972 -=- Motor Vehicle Administration -=--- Applicant's Personal Information --Full Name: Dominique Monay
219 Sex: Male Date of Birth: 06/10/1972
3. Return to Notepad
The Destructor of a Class While a constructor is a method used to initialize an instance of a class, a destructor is used to destruct an instance of class when that variable is not used anymore. Like the constructor, the destructor has the same name as the class. To indicate that the method is a destructor, its name is preceded with a tilde. Here is an example of a destructor in a class: using System; class SampleClass { // Constructor public SampleClass() { Console.WriteLine("SampleClass - Constructor"); }
}
~SampleClass() { Console.WriteLine("Destructor of SampleClass"); }
public class NewProject { static void Main() { SampleClass Sample = new SampleClass(); }
Console.WriteLine();
} This would produce: SampleClass - Constructor Destructor of SampleClass Like a (default) constructor, a destructor is automatically created for your class but you can also create it if you want. A class can have only one constructor. If you don't create it, the compiler would create it for your class. If you create it, the compiler would not create another. A destructor cannot have an access level. A destructor is called when the memory that a class was used is no longer needed. This is done automatically by the compiler. For this reason, you will hardly need to create a constructor, since its job is automatically taken care of behind the scenes by the compiler.
220
Previous
Copyright © 2004-2005 FunctionX, Inc.
Next
The Properties of a Class Overview of Properties Introduction In C++ and Java, when creating member variables of a class, programmers usually "hide" these members in private sections (C++) or create them as private (Java). This technique makes sure that a member variable is not accessed outside the class so that the clients of the class cannot directly influence the value of the member variable. If you create a member variable as private but still want other classes or methods to access or get the value of such a member variable, you must then create one or two methods used as "accessories", like a door in which the external methods or classes must pass through to access the member variable. A property is a member of a class that acts as an intermediary to a member variable of the class. For example, if you have a member variable of class and that member represents the salary of an employee, a property can be the "door" that other methods or classes that need the salary must present their requests to. As such, these external methods and class cannot just change the salary or retrieve it as they wish. A property can be used to validate their request, to reject or to accept them.
Accessories for Properties As mentioned already, a property is used to "filter" access to a member variable of a class. Therefore, you start by declaring a (private (if you don't make it private, you may be deceiving
221
the purpose of creating a property)) member variable: using System; namespace Geometry { public class Square { private double _side; } public class Applied { static void Main() { } }
} Obviously this private member variable cannot be accessed by a method or class outside of its class. Therefore, to let outside classes access this variable, you would/can create a property. To create a property, start with a member whose formula resembles a method without the parentheses. Here is an example:
using System; namespace Geometry { public class Square { private double _side; // This is a new property public double Side { } }
} With regards to their role, there are two types of properties.
Practical Learning: Introducing Properties 1. Start a new file in Notepad 2. From what we know so far, type the following: using System; namespace LamackEnterprises { public class DepartmentStore
222 {
}
private private private private private
string string string string double
itemNo; cat; name; size; price;
public class Exercise { static void Main() { }
}
}
3. Save it as exercise.cs in a new folder named DeptStore3 inside of your CSharp Lessons folder 4. To create a property for each member variable, change the DepartmentStore class as follows: using System; namespace LamackEnterprises { public class DepartmentStore { private string itemNo; private string cat; private string name; private string size; private double price; // A property for the stock number of an item public string ItemNumber { } // A property for the category of item public string Category { } // A property for an item's name of an item public string ItemName { } // A property for size of a merchandise public string Size { } // A property for the marked price of an item
223 public double UnitPrice { } } public class Exercise { static void Main() { } }
}
5. Save the file
Types of Properties Property Readers A property is referred to as read if its role is only to make available the value of the member variable it represents. To create a read property, in the body of the property, type the get keyword and create a body for the property, using the traditional curly brackets that delimit a section of code. Here is an example: using System; namespace Geometry { public class Square { private double _side; // This is a new property public double Side { get { } } }
} In the body of the get clause, you can implement the behavior that would be used to make the member variable's value available outside. The simplest way consists of just returning the corresponding member variable. Here is an example:
using System; namespace Geometry { public class Square { private double _side; // This is a new property
224
}
public double Side { get { return _side; } }
} A read property is also referred to as a read-only property because the clients of the class can only retrieve the value of the property but they cannot change it. Therefore, if you create (only) a read property, you should provide the users with the ability to primarily specify the value of the member variable. To do this, you can create an accessory method or a constructor for the class . Here is an example of such a constructor: using System; namespace Geometry { public class Square { private double _side; // This is a new property public double Side { get { return _side; } }
}
public Square(double s) { _side = s; }
} Once a read property has been created, other classes or methods can access it, for example they read its value as follows: using System; namespace Geometry { public class Square { private double _side; // This is a new property public double Side { get { return _side;
225
}
}
}
public Square(double s) { _side = s; }
class Applied { static void Main() { Square sq = new Square(-25.55); Console.WriteLine("Square Side: {0}", sq.Side); } }
} This would produce:
Square Side: -25.55 Press any key to continue We described a property as serving as a door from outside to its corresponding member variable, preventing those outside classes or method to alter the member variable. Notice that the Square class was given a negative value for the member variable, which is usually unrealistic for the side of a square. In this case and others, while still protecting the member variable as private, you can use the read property to reset the value of the member variable or even to reject it. To provide this functionality, you can create a conditional statement in the read property to perform a checking process. Here is an example: using System; namespace Geometry { public class Square { private double _side; // This is a new property public double Side { get { if( _side < 0 ) return 0; // else is implied return _side; } } public Square(double s) {
226
}
_side = s;
} class Applied { static void Main() { Square sq1 = new Square(-12.48); Square sq2 = new Square(25.55); Console.WriteLine("First Square Characteristics"); Console.WriteLine("Side: {0}\n", sq1.Side); Console.WriteLine("Second Square Characteristics"); Console.WriteLine("Side: {0}\n", sq2.Side); }
}
} This would produce: First Square Characteristics Side: 0 Second Square Characteristics Side: 25.55
Practical L
Classes Interactions Combinations of Classes Class Nesting A class can be created inside of another class. A class created inside of another is referred to as nested:
227
To nest a class, simply create it as you would any other. Here is an example of a class called Inside that is nested in a class called Outside: public class Outside { public class Inside { } } In the same way, you can nest as many classes as you wish in another class and you can nest as many classes inside of other nested classes if you judge it necessary. Just as you would manage any other class so can you exercise control on a nested class. For example, you can declare all necessary fields, properties, or methods in the nested class or in the nesting class. When you create one class inside of another, there is no special programmatic relationship between both classes: just because a class is nested does not mean that the nested class has immediate access to the members of the nesting class. They are two different classes and they can be used separately. The name of a nested class is not "visible" outside of the nesting class. To access a nested class outside of the nesting class, you must qualify the name of the nested class anywhere you want to use it. For example, if you want to declare an Inside variable somewhere in the program but outside of Outside, you must qualify its name. Here is an example: using System; public class Outside { public class Inside { public Inside() { Console.WriteLine(" -= Inside =-"); } } public Outside() { Console.WriteLine(" =- Outside -="); } } class Exercise { static void Main()
228 { }
Outside Recto = new Outside(); Outside.Inside Ins = new Outside.Inside();
} This would produce: =- Outside -= -= Inside =Because there is no programmatically privileged relationship between a nested class and its "container" class, if you want to access the nested class in the nesting class, you can use its static members. In other words, if you want, you can declare static all members of the nested class that you want to access in the nesting class. Here is an example: using System; public class Outside { public class Inside { public static string InMessage; public Inside() { Console.WriteLine(" -= Insider =-"); InMessage = "Sitting inside while it's raining"; }
Programming"); }
public static void Show() { Console.WriteLine("Show me the wonderful world of C# }
public Outside() { Console.WriteLine(" =- The Parent -="); }
}
public void Display() { Console.WriteLine(Inside.InMessage); Inside.Show(); }
class Exercise { static void Main() { Outside Recto = new Outside(); Outside.Inside Ins = new Outside.Inside(); Recto.Display();
229
}
} In the same way, if you want to access the nesting class in the nested class, you can go through the static members of the nesting class. To do this, you can declare static all members of the nesting class that you want to access in the nested class. Here is an example:
using System; public class Outside { public class Inside { public static string InMessage; public Inside() { Console.WriteLine(" -= Insider =-"); InMessage = "Sitting inside while it's raining"; } public static void Show() { Console.WriteLine("Show me the wonderful world of C# Programming");
}
} public void FieldFromOutside() { Console.WriteLine(Outside.OutMessage); }
private static string OutMessage; public Outside() { Console.WriteLine(" =- The Parent -="); OutMessage = "Standing outside! It's cold and raining!!"; } public void Display() { Console.WriteLine(Inside.InMessage); Inside.Show(); } } class Exercise { static void Main() { Outside Recto = new Outside(); Outside.Inside Ins = new Outside.Inside(); Recto.Display(); Console.WriteLine();
230
}
Ins.FieldFromOutside();
} This would produce: =- The Parent -= -= Insider =Sitting inside while it's raining Show me the wonderful world of C# Programming Standing outside! It's cold and raining!! Instead of static members, if you want to access members of a nested class in the nesting class, you can first declare a variable of the nested class in the nesting class. In the same way, if you want to access members of a nesting class in the nested class, you can first declare a variable of the nesting class in the nested class. Here is an example: using System; public class Outside { // A member of the nesting class private string OutMessage; // The nested class public class Inside { // A field in the nested class public string InMessage; // A constructor of the nested class public Inside() { Console.WriteLine(" -= Insider =-"); this.InMessage = "Sitting inside while it's raining"; } // A method of the nested class public void Show() { // Declare a variable to access the nesting class Outside outsider = new Outside(); Console.WriteLine(outsider.OutMessage); } } // End of the nested class // A constructor of the nesting class public Outside() { this.OutMessage = "Standing outside! It's cold and raining!!"; }
Console.WriteLine(" =- The Parent -=");
// A method of the nesting class public void Display()
231 {
Console.WriteLine(insider.InMessage);
} // Declare a variable to access the nested class Inside insider = new Inside(); } class Exercise { static void Main() { Outside Recto = new Outside(); Outside.Inside Ins = new Outside.Inside();
}
Ins.Show(); Recto.Display();
} This would produce: -= Insider ==- The Parent -= -= Insider =-= Insider ==- The Parent -= Standing outside! It's cold and raining!! Sitting inside while it's raining
A Class as a Field
Just like any of the variables we have used so far, you can make a class or a structure a member variable, also called a field, of another class. To use a class in your own class, of course you must have that class. You can use one of the classes already available in C# or you can first create your own class. Here is an example of a class: public class MVADate { private int DayHired; private int MonthHired; private int YearHired; } A field is a member variable created from another class instead of primitive types. To use a class as a member of your class, simply declare its variable as you would proceed with any of the member variables we have declared so far. Here is an example: using System; public class MVADate { private int DayHired; private int MonthHired; private int YearHired; } public class MotorVehicleAdministration
232 {
}
MVADate MDate; static int Main() { return 0; } After a class has been declared as a member variable of another class, it can be used regularly. Because the member is a class, declared as a reference (in (Managed) C++, it would be declared as a pointer) instead of a value type, there are some rules you must follow to use it. After declaring the member variable, you must make sure you have allocated memory for it on the heap. You must also make sure that the variable is initialized appropriately before it can be used; otherwise you would receive an error when compiling the file. Imagine you declare a variable of class A as a member of class B. If you declare a variable of class B in an external method, as we have done so far in Main(), to access a member of class A, you must fully qualify it.
Practical Learning: Declaring a Class as a Member Variable 1. Start a new file in Notepad and, in the empty file, type the following: using System; public class MVADate { private int dayOfBirth; private int monthOfBirth; private int yearOfBirth; public void SetDate(int d, int m, int y) { dayOfBirth = d; monthOfBirth = m; yearOfBirth = y; } public string ProduceDate() { string result = dayOfBirth + "/" + monthOfBirth + "/" + yearOfBirth; }
return result;
} public class MotorVehicleAdministration { public MotorVehicleAdministration() { birthdate = new MVADate(); }
233 private string fullName; private MVADate birthdate; private bool isAnOrganDonor; static int Main() { MotorVehicleAdministration MVA = new MotorVehicleAdministration(); Console.WriteLine("To process a registration, enter the information"); Console.Write("Full Name: "); MVA.fullName = Console.ReadLine(); Console.Write("Day of Birth: "); int d = int.Parse(Console.ReadLine()); Console.Write("Month of Birth: "); int m = int.Parse(Console.ReadLine()); Console.Write("Year of Birth: "); int y = int.Parse(Console.ReadLine()); Console.Write("Is the application an organ donor (0=No/1=Yes)? "); string ans = Console.ReadLine(); if( ans == "0" ) MVA.isAnOrganDonor = false; else MVA.isAnOrganDonor = true; MVA.birthdate.SetDate(d, m, y);
-=-");
Console.WriteLine("\n -=- Motor Vehicle Administration -=-"); Console.WriteLine(" -=- Driver's License Application
Console.WriteLine("Full Name: {0}", MVA.fullName); Console.WriteLine("Dateof Birth: {0}", MVA.birthdate.ProduceDate()); Console.WriteLine("Organ Donor? {0}", MVA.isAnOrganDonor);
}
Console.WriteLine(); return 0;
}
2. Save the file as exercise.cs in a new folder called MVA2 created inside your CSharp Lessons folder 3. Open the Command Prompt and switch to the folder that contains the current exercise
4. Compile the program with csc exercise.cs 5. Execute it by typing exercise Here is an example: C:\CSharp Lessons\MVA2>csc exercise.cs Microsoft (R) Visual C# .NET Compiler version 7.10.3052.4 for Microsoft (R) .NET Framework version 1.1.4322 Copyright (C) Microsoft Corporation 2001-2002. All rights reserved.
234
C:\CSharp Lessons\MVA2>exercise To process a registration, enter the information Full Name: Ernestine Mvouama Day of Birth: 8 Month of Birth: 14 Year of Birth: 1984 Is the application an organ donor (0=No/1=Yes)? 1 -=- Motor Vehicle Administration -=-=- Driver's License Application -=Full Name: Ernestine Mvouama Dateof Birth: 8/14/1984 Organ Donor? True 6. Return to Notepad
Classes and External Methods Returning a Class From a Method Like a value from regular type, you can return a class object from a method of a class. To do this, you can first declare the method and specify the class as the return type. Here is an example: using System; public class MVADate { } public class MotorVehicleAdministration { private static MVADate RequestDateOfBirth() { } static int Main() { MotorVehicleAdministration MVA = new MotorVehicleAdministration(); Console.WriteLine(); return 0; }
} After implementing the method, you must return a value that is conform to the class, otherwise you would receive an error when compiling the application. You can proceed by declaring a variable of the class in the body of the method, initializing the variable, and then returning it. Once a method has returned a value of a class, the value can be used as normally as possible.
235
Practical Learning: Returning a Class From a Method 1. Change the file as follows: using System; public class MVADate { private int dayOfBirth; private int monthOfBirth; private int yearOfBirth; public void SetDate(int d, int m, int y) { dayOfBirth = d; monthOfBirth = m; yearOfBirth = y; } public string ProduceDate() { string result = dayOfBirth + "/" + monthOfBirth + "/" + yearOfBirth; return result; }
}
public class MotorVehicleAdministration { public MotorVehicleAdministration() { birthdate = new MVADate(); } private string fullName; private MVADate RequestDateOfBirth(); private bool isAnOrganDonor; private static MVADate RequestDateOfBirth() { MVADate date = new MVADate(); Console.Write("Day of Birth: "); int d = int.Parse(Console.ReadLine()); Console.Write("Month of Birth: "); int m = int.Parse(Console.ReadLine()); Console.Write("Year of Birth: "); int y = int.Parse(Console.ReadLine());
}
date.SetDate(d, m, y); return date;
static int Main() {
236 MotorVehicleAdministration MVA = new MotorVehicleAdministration(); Console.WriteLine("To process a registration, enter the information"); Console.Write("Full Name: "); MVA.fullName = Console.ReadLine(); MVA.birthdate = RequestDateOfBirth(); Console.Write("Is the application an organ donor (0=No/1=Yes)?
");
string ans = Console.ReadLine(); if( ans == "0" ) MVA.isAnOrganDonor = false; else MVA.isAnOrganDonor = true;
-=-");
Console.WriteLine("\n -=- Motor Vehicle Administration -=-"); Console.WriteLine(" -=- Driver's License Application
Console.WriteLine("Full Name: {0}", MVA.fullName); Console.WriteLine("Dateof Birth: {0}", MVA.birthdate.ProduceDate()); Console.WriteLine("Organ Donor? {0}", MVA.isAnOrganDonor);
}
Console.WriteLine(); return 0;
} 2. Save it and switch to the Command Prompt 3. Compile and execute the application
Passing an Object as Argument Once a class has been created, it can be used like any other variable. For example, its variable can be passed as argument to a method of another class. When a class is passed as argument, its public members are available to the method that uses it. Here is an example: class CarRegistration { public void DisplayDriversLicense(MotorVehicleAdministration mva) { Console.WriteLine("Full Name: {0}", mva.fullName); Console.WriteLine("Dateof Birth: {0}", mva.birthdate.ProduceDate()); Console.WriteLine("Organ Donor? {0}", mva.isAnOrganDonor); } } public class MotorVehicleAdministration { public string fullName; public MVADate birthdate;
237 public bool
isAnOrganDonor;
} In the same way, you can pass more than one class as arguments to a method. Because classes are always used by reference, when passing a class as argument, it is implied to be passed by reference. To reinforce this, you can type the ref keyword to the left of the argument. Here is an example: class CarRegistration { public void DisplayDriversLicense(ref MotorVehicleAdministration mva) { Console.WriteLine("Full Name: {0}", mva.fullName); Console.WriteLine("Dateof Birth: {0}", mva.birthdate.ProduceDate()); Console.WriteLine("Organ Donor? {0}", mva.isAnOrganDonor); } }
Practical Learning: Passing a Class as Argument 1. To pass a class as argument, change the file as follows: using System; namespace ConsoleApplication1 { public class MVADate { private int dayOfBirth; private int monthOfBirth; private int yearOfBirth; public void SetDate(int d, int m, int y) { dayOfBirth = d; monthOfBirth = m; yearOfBirth = y; } public string ProduceDate() { string result = dayOfBirth + "/" + monthOfBirth + "/" + yearOfBirth; }
return result;
} class Car { public string Make; public string Model; public int CarYear; } class CarRegistration
238 { public void DisplayDriversLicense(MotorVehicleAdministration mva) { Console.WriteLine("\n -=- Motor Vehicle Administration
-=-");
Console.WriteLine(" -=- Car Registration -=-"); Console.WriteLine("Full Name: {0}", mva.fullName); Console.WriteLine("Dateof Birth: {0}", mva.birthdate.ProduceDate()); Console.WriteLine("Organ Donor? {0}", mva.isAnOrganDonor); } public void DisplayCarInformation(Car v) { Console.WriteLine("Car: {0} {1}", v.Make, v.Model); Console.WriteLine("Year: {0}", v.CarYear); } } public class MotorVehicleAdministration { public MotorVehicleAdministration() { birthdate = new MVADate(); } public public public public
string MVADate bool Car
fullName; birthdate; isAnOrganDonor; NewCar;
private static MVADate RequestDateOfBirth() { MVADate date = new MVADate(); Console.Write("Day of Birth: "); int d = int.Parse(Console.ReadLine()); Console.Write("Month of Birth: "); int m = int.Parse(Console.ReadLine()); Console.Write("Year of Birth: "); int y = int.Parse(Console.ReadLine());
}
date.SetDate(d, m, y); return date;
private static Car RegisterCar() { Car c = new Car(); Console.Write("Make: "); c.Make = Console.ReadLine(); Console.Write("Model: "); c.Model = Console.ReadLine(); Console.Write("Year: "); c.CarYear = int.Parse(Console.ReadLine());
239
}
return c;
static void Main() { MotorVehicleAdministration MVA = new MotorVehicleAdministration(); CarRegistration regist = new CarRegistration(); Car vehicle = new Car(); Console.WriteLine("To process a registration, enter the
information");
Console.Write("Full Name: "); MVA.fullName = Console.ReadLine(); MVA.birthdate = RequestDateOfBirth(); Console.Write("Is the application an organ donor (0=No/1=Yes)? ");
string ans = Console.ReadLine(); if( ans == "0" ) MVA.isAnOrganDonor = false; else MVA.isAnOrganDonor = true; Console.WriteLine("Enter the following information for Car
Registration");
MVA.NewCar = RegisterCar(); regist.DisplayDriversLicense(MVA); regist.DisplayCarInformation(MVA.NewCar); Console.WriteLine(); }
}
} 2. Save it and switch to the Command Prompt 3. Compile and execute the application. Here is an example: To process a registration, enter the information Full Name: Alan Scott Day of Birth: 2 Month of Birth: 10 Year of Birth: 1974 Is the application an organ donor (0=No/1=Yes)? 0 Enter the following information for Car Registration Make: Ford Model: Crown Victoria Year: 1998 -=- Motor Vehicle Administration -=-=- Car Registration -=-
240 Full Name: Dateof Birth: Organ Donor? Car: Year:
Alan Scott 2/10/1974 False Ford Crown Victoria 1998
4. Return to Notepad
Previous
Copyright © 2004-2006 FunctionX, Inc.
Next
Inheritance Introduction to Inheritance Definition
Volley Ball
Football
Basketball
Handball
Golf
The primary characteristic of the objects on the above pictures is that they are balls used in different sports. Another characteristic they share is that they are round. Although these balls are used in sport, one made for one sport cannot (or should not) be used in another sport (of course, it is not unusual for a footballer to mess with a volley ball on a lawn but it is not appropriate). The common characteristics of these objects can be listed in a group like a C# class. The class would appear as: class Ball { TypeOfSport; Size; } If you were asked to create a class to represent these balls, you may be tempted to implement a general class that defines each ball. This may be a bad idea because, despite their round resemblance, there are many internal differences among these balls. Programming languages like C# provide an alternate solution to this type of situation. Inheritance consists of creating a class whose primary definition or behavior is based on another class. In other words, inheritance starts by having a class that can provide behavior that other classes can improve on.
241
Practical Learning: Introducing Inheritance 1. Start Notepad and, in the empty file, type the following: using System; public class Applicant { private string private string private string private string private string private string private string private int private string private int
name; addr; ct; stt; ZIP; sex; dob; wgt; hgt; race;
public Applicant() { } public Applicant(string n) { this.name = n; } public Applicant(string n, string s) { this.name = n; this.sex = s; } public string FullName { get { return name; } set { name = value; } } public string Gender { get { return sex; } set { sex = value; } } public void Registration() { char s; Console.Write("Full Name: "); this.name = Console.ReadLine(); do
242 { Console.Write("Sex(F=Female/M=Male): "); s = char.Parse(Console.ReadLine()); if( (s != 'f') && (s != 'F') && (s != 'm') && (s != 'M') )
Console.WriteLine("Please enter a valid
character"); 'M') );
}
sex = "Male"; }while( (s != 'f') && (s != 'F') && (s != 'm') && (s != if( (s == 'f') || s == 'F' ) sex = "Female"; else if( (s == 'm') || (s == 'M') ) sex = "Male";
public void Show() { Console.WriteLine("Full Name: Console.WriteLine("Sex: }
{0}", this.name); {0}", this.sex);
} public class Exercise { public static int Main() { Applicant person = new Applicant(); Console.WriteLine(" -=- Motor Vehicle Administration -=-"); person.Registration(); Console.WriteLine("\n -=- Motor Vehicle Administration -=-");
person.Show();
}
Console.WriteLine(); return 0;
}
2. Save the file in a new folder named MVA3 3. Save the file itself as Exercise.cs in the MVA3 folder 4. Open the Command Prompt and change to the MVA3 folder
5. Compile the program by typing csc Exercise.cs and press Enter 6. Execute the program by typing Exercise and press Enter. Here is an example: -=- Motor Vehicle Administration -=Full Name: Alexis Langa Sex(F=Female/M=Male): P Please enter a valid character
243 Sex(F=Female/M=Male): F -=- Motor Vehicle Administration -=Full Name: Alexis Langa Sex: Female 7. Return to Notepad
Class Derivation As you may have guess, in order to implement inheritance, you must first have a class that provides the fundamental definition or behavior you need. There is nothing magical about such a class. It could appear exactly like any of the classes we have used so far. Here is an example: using System; class Circle { private double _radius; public double Radius { get { if( _radius < 0 ) return 0.00; else return _radius; } set { _radius = value; } } public double Diameter { get { return Radius * 2; } } public double Circumference { get { return Diameter * 3.14159; } } public double Area { get { return Radius * Radius * 3.14159; } } }
244 class Exercise { public static int Main() { Circle c = new Circle(); c.Radius = 25.55; Console.WriteLine("Circle Characteristics"); Console.WriteLine("Side: {0}", c.Radius); Console.WriteLine("Diameter: {0}", c.Diameter); Console.WriteLine("Circumference: {0}", c.Circumference); Console.WriteLine("Area: {0}", c.Area); return 0; }
} This would produce:
Circle Characteristics Side: 25.55 Diameter: 51.1 Circumference: 160.535249 Area: 2050.837805975 Press any key to continue The above class is used to process a circle. It can request or provide a radius. It can also calculate the circumference and the area of a circle. Now, suppose you want to create a class for a sphere. You could start from scratch as we have done so far. On the other hand, since a sphere is primarily a 3-dimensional circle, and if you have a class for a circle already, you can simply create your sphere class that uses the already implemented behavior of a circle class. Creating a class that is based on another class is also referred to as deriving a class from another. The first class serves as parent or base. The class that is based on another class is also referred to as child or derived. To create a class based on another, you use the following formula: class NewChild : Base { // Body of the new class } In this formula, you start with the class keyword followed by a name from your class. On the right side of the name of your class, you must type the : operator, followed by the name of the class that will serve as parent. Of course, the Base class must have been defined; that is, the compiler must be able to find its definition. Based on the above formula, you can create a sphere class based on the earlier mentioned Circle class as follows: class Sphere : Circle { // The class is ready } After deriving a class, it becomes available and you can use it just as you would any other class. Here is an example: using System;
245
class Circle { private double _radius; public double Radius { get { if( _radius < 0 ) return 0.00; else return _radius; } set { _radius = value; } } public double Diameter { get { return Radius * 2; } } public double Circumference { get { return Diameter * 3.14159; } } public double Area { get { return Radius * Radius * 3.14159; } } } class Sphere : Circle { } class Exercise { public static int Main() { Circle c = new Circle(); c.Radius = 25.55; Console.WriteLine("Circle Characteristics"); Console.WriteLine("Side: {0}", c.Radius); Console.WriteLine("Diameter: {0}", c.Diameter); Console.WriteLine("Circumference: {0}", c.Circumference);
246 Console.WriteLine("Area:
{0}", c.Area);
Sphere s = new Sphere(); s.Radius = 25.55; Console.WriteLine("\nSphere Characteristics"); Console.WriteLine("Side: {0}", s.Radius); Console.WriteLine("Diameter: {0}", s.Diameter); Console.WriteLine("Circumference: {0}", s.Circumference); Console.WriteLine("Area: {0}", s.Area); return 0; }
} This would produce:
Circle Characteristics Side: 25.55 Diameter: 51.1 Circumference: 160.535249 Area: 2050.837805975 Sphere Characteristics Side: 25.55 Diameter: 51.1 Circumference: 160.535249 Area: 2050.837805975 Press any key to continue When a class is based on another class, all public (we will also introduce another inheritanceoriented keyword for this issue) members of the parent class are made available to the derived class that can use them as easily. While other methods and classes can also use the public members of a class, the difference is that the derived class can call the public members of the parent as if they belonged to the derived class. That is, the child class doesn't have to "qualify" the public members of the parent class when these public members are used in the body of the derived class. This is illustrated in the following program: using System; class Circle { private double _radius; public double Radius { get { if( _radius < 0 ) return 0.00; else return _radius; } set { _radius = value; }
247 } public double Diameter { get { return Radius * 2; } } public double Circumference { get { return Diameter * 3.14159; } } public double Area { get { return Radius * Radius * 3.14159; } }
}
public void ShowCharacteristics() { Console.WriteLine("Circle Characteristics"); Console.WriteLine("Side: {0}", Radius); Console.WriteLine("Diameter: {0}", Diameter); Console.WriteLine("Circumference: {0}", Circumference); Console.WriteLine("Area: {0}", Area); }
class Sphere : Circle { public void ShowCharacteristics() { // Because Sphere is based on Circle, you can access // any public member(s) of Circle without qualifying it(them) Console.WriteLine("\nSphere Characteristics"); Console.WriteLine("Side: {0}", Radius); Console.WriteLine("Diameter: {0}", Diameter); Console.WriteLine("Circumference: {0}", Circumference); Console.WriteLine("Area: {0}\n", Area); } } class Exercise { public static int Main() { Circle c = new Circle(); c.Radius = 25.55; c.ShowCharacteristics(); Sphere s = new Sphere();
248
s.Radius = 25.55; s.ShowCharacteristics(); }
return 0;
} This would produce the same result.
Practical Learning: Inheriting 1. To derive a class, change the file as follows: using System; public enum TypeOfIDCardApplication { NewCard = 1, Replacement, Correction, Renewal, Transfer } public class Applicant { private string private string private string private string private string private string private string private int private string private int
name; addr; ct; stt; ZIP; sex; dob; wgt; hgt; race;
public Applicant() { } public Applicant(string n) { this.name = n; } public Applicant(string n, string s) { this.name = n; this.sex = s; } public string FullName {
249
}
get { return name; } set { name = value; }
public string Gender { get { return sex; } set { sex = value; } } public void Registration() { char s; Console.Write("Full Name: "); this.name = Console.ReadLine(); do {
Console.Write("Sex(F=Female/M=Male): "); s = char.Parse(Console.ReadLine());
if( (s != 'f') && (s != 'F') && (s != 'm') && (s != 'M') ) Console.WriteLine("Please enter a valid character"); sex = "Male"; }while( (s != 'f') && (s != 'F') && (s != 'm') && (s != 'M') );
}
if( (s == 'f') || s == 'F' ) sex = "Female"; else if( (s == 'm') || (s == 'M') ) sex = "Male";
public void Show() { Console.WriteLine("Full Name: Console.WriteLine("Sex: }
{0}", this.name); {0}", this.sex);
} public class IdentityCard : Applicant { public int ApplicationReason; public int TypeOfAnswer; public string TransferFrom; public string NotesOrComments; public void CreateIDCard() { do { Console.WriteLine("What's the Console.WriteLine("1 - I need Console.WriteLine("2 - I need Console.WriteLine("3 - I need
reason you need an Identity Card?"); a new ID Card"); to replace my ID Card"); a correction on my ID Card");
250 Console.WriteLine("4 - I want to renew my current ID Card"); Console.WriteLine("5 - I want to transfer my ID Card"); Console.Write("Your Choice: "); ApplicationReason = int.Parse(Console.ReadLine());
if( ApplicationReason < 1 || ApplicationReason > 5 ) Console.WriteLine("\nPlease enter a valid number between 1 and 5"); } while(ApplicationReason < 1 || ApplicationReason > 5); this.Registration(); switch((TypeOfIDCardApplication)ApplicationReason) { case TypeOfIDCardApplication.NewCard: break;
case TypeOfIDCardApplication.Replacement: do { Console.WriteLine("What is the reason you want a replacemen Console.WriteLine("1 - I lost my ID Card"); Console.WriteLine("2 - My ID Card was stolen"); Console.WriteLine("3 - My ID Card is damaged"); Console.WriteLine("4 - The court/a judge ordered that I rep Console.Write("Your Choice: "); TypeOfAnswer = int.Parse(Console.ReadLine()); if( TypeOfAnswer < 1 || TypeOfAnswer > 4 ) Console.WriteLine("Please enter the correct answer") } while( TypeOfAnswer < 1 || TypeOfAnswer > 4 ); Console.WriteLine("Write the applican't description"); NotesOrComments = Console.ReadLine(); break;
wright");
case TypeOfIDCardApplication.Correction: do { Console.WriteLine("What is the reason you want a correction Console.WriteLine("5 - There is an error on the card"); Console.WriteLine("6 - The picture (only the picture) on it
Console.WriteLine("7 - I got married"); Console.WriteLine("8 - I got a divorce"); Console.Write("Your Choice: "); TypeOfAnswer = int.Parse(Console.ReadLine()); if( TypeOfAnswer < 5 || TypeOfAnswer > 8 ) Console.WriteLine("Please enter the correct answer") } while( TypeOfAnswer < 5 || TypeOfAnswer > 8 ); Console.WriteLine("Write the applican't description"); NotesOrComments = Console.ReadLine(); break; case TypeOfIDCardApplication.Renewal: break;
251
case TypeOfIDCardApplication.Transfer: Console.WriteLine("What US state or Canadian province are you trans
from?");
TransferFrom = Console.ReadLine(); break; }
}
public void ShowIDCard() { switch((TypeOfIDCardApplication)ApplicationReason) { case TypeOfIDCardApplication.NewCard: Console.WriteLine("Application for New Identity Card"); break; case TypeOfIDCardApplication.Replacement: Console.WriteLine("Application for Identity Card Replacement"); break; case TypeOfIDCardApplication.Correction: Console.WriteLine("Application for Identity Card Correction"); break; case TypeOfIDCardApplication.Renewal: Console.WriteLine("Application for Identity Card Renewal"); break; case TypeOfIDCardApplication.Transfer: Console.WriteLine("Application for Identity Card Transfer"); Console.WriteLine("Identity Card Transferred From: {0}", TransferFr break; }
}
Console.WriteLine("Applicant's Information"); this.Show(); Console.WriteLine("Administration Notes or Comments"); Console.WriteLine(NotesOrComments);
} public class Exercise { public static int Main() { int ReasonToBeHereToday; Console.WriteLine(" -=- Motor Vehicle Administration -=-"); do {
Console.WriteLine("So what brought you to the Motor Vehicle Department toda Console.WriteLine("1 - I need an Identity Card"); Console.WriteLine("2 - I need a Driver's License"); Console.WriteLine("3 - I want to register to vote"); Console.Write("Your Choice: "); ReasonToBeHereToday = int.Parse(Console.ReadLine()); if( ReasonToBeHereToday < 1 || ReasonToBeHereToday > 3 ) Console.WriteLine("Please enter a valid number as 1, 2, or 3"); } while( ReasonToBeHereToday < 1 || ReasonToBeHereToday > 3 );
252
switch(ReasonToBeHereToday) { case 1: IdentityCard IDApplicant = new IdentityCard(); IDApplicant.CreateIDCard(); Console.WriteLine("\n -=- Motor Vehicle Administration -=-"); IDApplicant.ShowIDCard(); break; case 2: Console.WriteLine("Come back tomorrow"); break; case 3: Console.WriteLine("Come back in two days"); break; } Console.WriteLine(); return 0; }
}
2. Save, compile, and test the file. Here is an example: -=- Motor Vehicle Admi
Polymorphism and Abstraction Characteristics of Inheritance Namespaces and Inheritance Imagine you had created a class named Person in a namespace named People as follows: Source File: Persons.cs using System; namespace People { public class Person { private string _name; private string _gdr; public Person() { this._name = "Not Available"; this._gdr = "Unknown";
253 } public Person(string name, string gender) { this._name = name; this._gdr = gender; } private string FullName { get { return _name; } set { _name = value; } }
}
private string Gender { get { return _gdr; } set { _gdr = value; } }
} If you decide to derive a class from it, remember that this class belongs to a namespace. To inherit from this class, the compiler will need to know the namespace in which the was created. Class inheritance that involves namespaces relies on qualification, like the calling of the members of a namespace. To derive a class from a class member of a namespace, type the name of the namespace, followed by the period operator ".", and followed by the name of the base namespace. Here is an example: Source File: StaffMembers.cs using System; namespace HighSchool { public class Teacher : People.Person { private string _pos; public Teacher() { this._pos = "Staff Member"; } public Teacher(string pos) { this._pos = pos; }
}
private string Position { get { return _pos; } set { _pos = value; } }
} If you need to call the class that was defined in a different namespace, remember to qualify its name
254
with the scope access operator. Here is an example: Source File: Exercise.cs using System; class Exercise { static void Main() { People.Person man = new People.Person("Hermine Sandt", "Male"); HighSchool.Teacher staff = new HighSchool.Teacher("Vice Principal"); }
Console.WriteLine();
} Alternatively, as mentioned in the past, to use the contents of a namespace, prior to calling a member of that namespace, you can type the using keyword followed by the name of the namespace. Here is an example: Source File: Exercise.cs using System; using People; using HighSchool; class Exercise { static void Main() { Person man = new Person("Hermine Sandt", "Male"); Teacher staff = new Teacher("Vice Principal"); }
Console.WriteLine();
}
Practical Learning: Using Inheritance With Namespaces 1. Open Notepad and type the following: using System; namespace FlatShapes { class Square { private double _side; public Square() { _side = 0.00; } public Square(double s)
255 { }
_side = s;
} class Rectangle { double _length; double _height; public Rectangle() { _length = 0.00; _height = 0.00; } public Rectangle(double L, double H) { _length = L; _height = H; } }
}
2. Save the file in a new folder named Shapes1 3. Save the file itself as Regulars.cs 4. Start another instance of Notepad and type the following: using System; class Exercise { static void Main() { FlatShapes.Square Sq = new FlatShapes.Square(24.55); } }
5. Save the file as Exercise.cs in the same Shapes1 folder 6. Open the Command Prompt and switch to the above Shapes1 folder
7. To compile the project, type csc Exercise.cs Regulars.cs and press Enter 8. To execute the project, type Exercise and press Enter 9. Return to Notepad
Protected Members To maintain a privileged relationship with its children, a parent class can make a set list of members available only to classes derived from it. With this relationship, some members of a parent class have a protected access level. Of course, as the class creator, it is your job to specify this relationship. To create a member that derived classes only can access, type the protected keyword to its left.
256
Here are examples: Source File: Persons.cs using System; namespace People { public class Person { private string _name; private string _gdr; public Person() { this._name = this._gdr } public Person(string { this._name = this._gdr = }
"Not Available"; = "Unknown"; name, string gender) name; gender;
protected string FullName { get { return _name; } set { _name = value; } } protected string Gender { get { return _gdr; } set { _gdr = value; } } public void Show() { Console.WriteLine("Full Name: {0}", this.FullName); Console.WriteLine("Gender: {0}", this.Gender); } }
} You can access protected members only in derived classes. Therefore, if you instantiate a class outside, you can call only public members: Source File: Exercise.cs using System; class Exercise { static void Main() { People.Person man = new People.Person("Hermine Sandt", "Male");
257 Console.WriteLine("Staff Member"); man.Show(); }
Console.WriteLine();
} This would produce: Staff Member Full Name: Hermine Sandt Gender: Male
Virtual Members We have just mentioned that you can create a new version of a member in a derived class for a member that already exists in the parent class. After doing this, when you call that member in your program, you need to make sure that the right member gets called, the member in the base class or the equivalent member in the derived class. When you create a base class, if you anticipate that a certain property or method would need to be redefined in the derived class, you can indicate this to the compiler. On the other hand, while creating your classes, if you find out that you are customizing a property of method that already existed in the base class, you should let the compiler that you are providing a new version. In both cases, the common member should be created as virtual. To do this, in the base class, type the virtual keyword to the left of the property or method. Based on this, the Area property of our Circle class can be created as follows: class Circle { public virtual double Area { get { return Radius * Radius * 3.14159; } } } In fact, in C#, unlike C++, if you omit the virtual keyword, the compiler would display a warning. When you derive a class from an abstract, since the methods (if any) of the abstract class were not implemented, you must implement each one of them in the derived class. When customizing virtual members in a derived class, to indicate that a member is already virtual in the base class and that you are defining a new version, type the override keyword to the left of its declaration. For example, the Area property in our Sphere class can be created as follows: class Sphere : Circle { public override double Area { get { return 4 * Radius * Radius * 3.14159; } }
258
}
public double Volume { get { return 4 * 3.14159 * Radius * Radius * Radius; } } In the same way, when implementing an abstract method of a class, type the override keyword to its left.
Practical Learning: Using Virtual Members 1. Start a new instance of Notepad and type the following: class ShapeDescription { public virtual string Description() { string Msg = "A quadrilateral is a geometric figure that has " + "four sides and four angles."; return Msg; } }
2. Save the file as Quadrilaterals.cs in the Shapes1 folder 3. Access the Regulars.cs file and override the Description method in the FlatShapes.Square and the FlatShapes.Rectangle classes as follows: using System; namespace FlatShapes { class Square : ShapeDescription { private double _side; public Square() { _side = 0.00; } public Square(double s) { _side = s; } public override string Description() { // Get the introduction from the parent string Introduction = base.Description() +
259 "\nA square is a quadrilateral that has four " + "equal sides and four right
angles";
}
return Introduction;
} class Rectangle : ShapeDescription { double _length; double _height; public Rectangle() { _length = 0.00; _height = 0.00; } public Rectangle(double L, double H) { _length = L; _height = H; } public override string Description() { // Get the introduction from the parent string Introduction = base.Description(); string Msg = Introduction + "\nA rectangle is a quadrilateral that has
adjacent " +
"perpendicular sides. This implies that its four " + "angles are right."; return Msg; } }
}
4. Save the Regulars.cs file 5. To access the new methods, access the Exercise.cs and change it as follows: using System; class Exercise { static void DisplaySquare(FlatShapes.Square S) { Console.WriteLine("Square Characteristics"); Console.WriteLine("Description: {0}", S.Description()); } static void DisplayRectangle(FlatShapes.Rectangle R)
260 { Console.WriteLine("Rectangle Characteristics"); Console.WriteLine("Description: {0}", R.Description()); } static void Main() { FlatShapes.Square Sq = new FlatShapes.Square(); FlatShapes.Rectangle Rect = new FlatShapes.Rectangle(); Console.WriteLine("========================================"); DisplaySquare(Sq); Console.WriteLine("========================================"); DisplayRectangle(Rect); Console.WriteLine("========================================"); }
Console.WriteLine();
} 6. Save the Exercise.cs 7. Switch to the Command Prompt to the Shapes1 folder
8. To compile the project, type csc Exercise.cs Regulars.cs Quadrilaterals.cs and press Enter 9. To execute the project, type Exercise and press Enter. This would produce: ======================================== Square Characteristics Description: A quadrilateral is a geometric figure that has four sides and four angles.A square is a quadrilateral that has four equal sides and four right angles ======================================== Rectangle Characteristics Description: A quadrilateral is a geometric figure that has four sides and four angles. A rectangle is a quadrilateral that has adjacent perpendicular sides. This implies that its four angles are right. ======================================== 10. Return to Notepad
Abstract Classes In C#, you can create a class whose role is only meant to provide fundamental characteristics for other classes. This type of class cannot be used to declare a variable of the object. Such a class is referred to as abstract. Therefore, an abstract class can be created only to serve as a parent class for others. To create an abstract class, type the abstract keyword to the left of its name. Here is an
261
example: abstract class Ball { protected int TypeOfSport; protected string Dimensions; }
Practical Learning: Creating an Abstract Class 1. To create an abstract class, in the Regulars.cs class, type the abstract keyword at the beginning of the class creation line: abstract class ShapeDescription { public virtual string Description() { string Msg = "A quadrilateral is a geometric figure that has " + "four sides and four angles."; return Msg; } } 2. Save the file
Abstract Properties and Methods When creating a class that would mainly be used as base for future inheritance, you can create one or more properties and make them abstract. To do this, when creating the property, type the abstract keyword to its left. Because you would not define the property, you can simply type the get keyword and its semi-colon in the body of the property. A method of a class also can be made abstract. An abstract method can be a member of only an abstract class. If you make a method abstract in a class, you must not implement the method. To create an abstract method, when creating its class, type the abstract keyword to the left of the method's name. End the declaration with a semi-colon and no body for the method since you cannot implement it. Here is an example: public abstract class Ball { protected int TypeOfSport; protected string Dimensions; }
public abstract CalculateArea(); In the same way, you can create as many properties and methods as you see fit. You can choose what properties and methods to make abstract. This is important for inheritance.
Practical Learning: Creating an Abstract Property 1. To create an abstract property, access the Quadrilaterals.cs file and change its class as follows: abstract class ShapeDescription { public abstract string Name { get; }
262
+
public virtual string Description() { string Msg = "A quadrilateral is a geometric figure that has " return Msg;
}
"four sides and four angles.";
}
2. Save the Quadrilaterals.cs file 3. To define the property, open the Regulars.cs file and change it as follows: using System; namespace FlatShapes { class Square : ShapeDescription { private double _side; public Square() { _side = 0.00; } public Square(double s) { _side = s; } public override string Name { get { return "Square"; } } public override string Description() { // Get the introduction from the parent string Introduction = base.Description() + "A square is a quadrilateral that has four " + "equal sides and four right angles";
}
return Introduction;
} class Rectangle : ShapeDescription { double _length; double _height; public Rectangle() { _length = 0.00;
263 _height = 0.00; } public Rectangle(double L, double H) { _length = L; _height = H; } public override string Name { get { return "Rectangle"; } } public override string Description() { // Get the introduction from the parent string Introduction = base.Description(); string Msg = Introduction + "\nA rectangle is a quadrilateral that has
adjacent " +
"perpendicular sides. This implies that its four
" +
"angles are right."; return Msg; }
}
} 4. Save the Regulars.cs file 5. To include the new property in the test, access the Exercise.cs file and change it as follows: using System; class Exercise { static void DisplaySquare(FlatShapes.Square S) { Console.WriteLine("Square Characteristics"); Console.WriteLine("Name: {0}", S.Name); Console.WriteLine("Description: {0}", S.Description()); } static void DisplayRectangle(FlatShapes.Rectangle R) { Console.WriteLine("Rectangle Characteristics"); Console.WriteLine("Name: {0}", R.Name); Console.WriteLine("Description: {0}", R.Description()); } static void Main() { FlatShapes.Square Sq = new FlatShapes.Square(); FlatShapes.Rectangle Rect = new FlatShapes.Rectangle();
264
Console.WriteLine("========================================"); DisplaySquare(Sq); Console.WriteLine("========================================"); DisplayRectangle(Rect); Console.WriteLine("========================================"); }
Console.WriteLine();
} 6. Save the Exercise.cs
7. To compile the project, type csc Exercise.cs Regulars.cs Quadrilaterals.cs and press Enter 8. To execute the project, type Exercise and press Enter. This would produce: ======================================== Square Characteristics Name: Square Description: A quadrilateral is a geometric figure that has four sides and four angles.A square is a quadrilateral that has four equal sides and four right angl es ======================================== Rectangle Characteristics Name: Rectangle Description: A quadrilateral is a geometric figure that has four sides and four angles. A rectangle is a quadrilateral that has adjacent perpendicular sides. This impli es that its four angles are right. ======================================== 9. Return to Notepad
Sealed Classes Any of the classes we have used so far in our lessons can be inherited from. If you create a certain class and don't want anybody to derive another class from it, you can mark it as sealed. In other words, a sealed class is one that cannot serve as base for another class. To mark a class as sealed, type the sealed keyword to its left. Here is an example: public sealed class Ball { public int TypeOfSport; public string Dimensions; }
Interfaces Introduction Imagine you start creating a class and, while implementing or testing it, you find out that this
265
particular class can be instead as a general base that other classes can be derived from. An interface is a special class whose purpose is to serve as a template that actual classes can be based on. An interface is primarily created like a class: it has a name, a body and can have members. To create an interface, instead of the class keyword, you use the interface keyword. By convention, the name of an interface starts with I. Here is an example: interface ICourtDimensions { }
Practical Learning: Introducing Interfaces 1. Access the Quadrilaterals.cs file. To create an interface, change the file as follows: interface IQuadrilateral { } abstract class ShapeDescription { public abstract string Name { get; } public virtual string Description() { string Msg = "A quadrilateral is a geometric figure that has " + "four sides and four angles."; return Msg; } } 2. Save the file
The Members of an Interface As done for a class, the members of an interface are listed in its body. In an interface, you cannot declare fields like those we have used in other classes. Instead, if you want some type of member variable, you can create a property. If you create a property in an interface, you cannot define that property. One of the rules of an interface is that you cannot define any of its members. This is also valid for its properties. Therefore, if you create a property in an interface: •
You can indicate that it would be read-only by adding it an empty getter. Here is an example: public interface ICourtDimensions { double Length { get; } }
•
You can indicate that it would be write-only. Here is an example: public interface ICourtDimensions { double Length { set; } }
•
You can indicate that it would be used to write values to it and to read values from it. Here is an
266 example: public interface ICourtDimensions { double Length { get; set; } } In the same way, you can create as many properties as you judge them necessary in an interface. Besides the properties, an interface can also have other types of members such as methods. Here is an example of an interface that has one read-only property named NameOfSport, one read/write property named NumberOfPlayers, and one method named SportCharacteristics: public interface IBall { int NumberOfPlayers { get; set; } string NameOfSport { get; } void SportCharacteristics(); }
Practical Learning: Creating Members of an Interface 1. To create a member int the new interface, access the Quadrilateral.cs file and change it as follows: interface IQuadrilateral { double Area { get; } } abstract class ShapeDescription { public abstract string Name { get; } public virtual string Description() { string Msg = "A quadrilateral is a geometric figure that has " + "four sides and four angles."; return Msg; } } 2. Save the file
An Interface as a Base Class An interface is mostly used to lay a foundation for other classes. For this reason, it is the prime
267
candidate for class derivation. To derive from an interface, use the same technique we have applied in inheritance so far. Here is an example of a class named SportBall that derives from an interface named ISportType: public class SportBall : ISportType { int players; string sport; } Just as you can derive a class from an interface, you can create an interface that itself is based on another interface. Here is an example: public interface ISportType : IBall { SportCategory Type { get; } } The C# language doesn't allow multiple inheritance which is the ability to create a class based on more than one class. Multiple inheritance is allowed only if the bases are interfaces. To create multiple inheritance, separate the names of interface with a comma. Here is an example: public interface ISportType : IBall, ICourtDimensions { SportCategory Type { get; } } You can also involve a class as parent in a multiple inheritance scenario but there must be only one class. Here is an example in which a class called Sports derives from one class and various interfaces: public interface Sports: Player, IBall, ICourtDimensions { }
Practical Learning: Inheriting From an Interface 1. To inherit an interface from another interface, access the Quadrilateral.cs file and change it as follows: interface IQuadrilateral { double Area { get; } } abstract class ShapeDescription { public abstract string Name { get; } public virtual string Description() {
268 string Msg = "A quadrilateral is a geometric figure that has " + }
"four sides and four angles."; return Msg;
} interface IRightAngles : IQuadrilateral { double Base { get; set; } double Height { get; set; } double Perimeter { get; } } 2. Save the file 3. To inherit a class from an interface, access the Regulars.cs file and change it as follows: using System; namespace FlatShapes { class Square : ShapeDescription, IRightAngles { . . . No Change } class Rectangle : ShapeDescription, IRightAngles { . . . No Change } } 4. Save the file
Implementation of Derived Classes of an Interface After creating an interface, you can derive other interfaces or other classes from it. If you are deriving other interfaces from an interface, you can just proceed as you see fit. For example, you can add or not add one or more new properties, you can add or not add one or more properties, etc. Here is an example: Source File: Preparation.cs public enum SportCategory { SinglePlayer, Collective, Unknown } public interface ICourtDimensions { double Length { get; set; } double Width { get; set; } } public interface IBall
269 { int NumberOfPlayers { get; set; } string NameOfSport { get; } void SportCharacteristics(); } public interface ISportType : IBall, ICourtDimensions { SportCategory Type { get; } } If you derive a class, from an interface, you must implement all properties that created in the interface. This means that you must define them so that, when a variable is declared of that class, the properties have meaning. In the same way, if you create a class that is based on an interface, you must implement all methods that were declared in the interface. If you derive a class from an interface that itself was derived from another interface, in your class, you must define all properties that were created in the whole lineage and you must implement all methods that were created in the parent and grant-parent interfaces. Here is an example: Source File: Sport.cs using System; public class SportBall : ISportType { int players; string sport; SportCategory _type; double Len; double Wdt; public SportBall(int nbr, SportCategory tp, string name) { players = nbr; _type = tp; sport = name; } public int NumberOfPlayers { get { return players;} set { players = value;} } public string NameOfSport
270 { }
get
{ return sport; }
public SportCategory Type { get { return _type; } } public double Length { get { return Len; } set { Len = value; } } public double Width { get { return Wdt; } set { Wdt = value; } } public void SportCharacteristics() { Console.WriteLine("Sport Characteristics"); Console.WriteLine("Name of Sport: {0}", NameOfSport); Console.WriteLine("Type of Sport: {0}", Type); Console.WriteLine("# of Players: {0}", NumberOfPlayers); Console.WriteLine("Court Dimensions: {0}m x {1}m", Len, Wdt); } } Once the class is ready, you can then use it as you see fit. Here is an example: Source File: Exercise.cs using System; class Exercise { static void Main() { SportBall volley = new SportBall(6, SportCategory.Collective, "Volley Ball"); volley.Length = 18; volley.Width = 9; volley.SportCharacteristics(); Console.WriteLine(); SportBall tennis = new SportBall(1, SportCategory.SinglePlayer, "Table Tennis"); tennis.Length = 23.7; tennis.Width = 8.25; tennis.SportCharacteristics(); Console.WriteLine(); }
} This would produce:
271 Sport Characteristics Name of Sport: Volley Ball Type of Sport: Collective # of Players: 6 Court Dimensions: 18m x 9m Sport Characteristics Name of Sport: Table Tennis Type of Sport: SinglePlayer # of Players: 1 Court Dimensions: 23.7m x 8.25m
Practical Learning: Implementing Derived Members of an Interface 1. To implement the members of an interface, access the Regulars.cs file and change it as follows: using System; namespace FlatShapes { class Square : ShapeDescription, IRightAngles { private double _side; public Square() { _side = 0.00; } public Square(double s) { _side = s; } public override string Name { get { return "Square"; } }
" +
public override string Description() { // Get the introduction from the parent string Introduction = base.Description() + "A square is a quadrilateral that has four "equal sides and four right angles"; return Introduction; } public double Base { get {
272 return (_side < 0) ? 0.00 : _side; } set { }
_side = value;
}
public double Height { get { return (_side < 0) ? 0.00 : _side; } set { _side = value; } } public double Area { get { return Base * Base; } } public double Perimeter { get { return Base * 4; } } } class Rectangle : ShapeDescription, IRightAngles { double _length; double _height; public Rectangle() { _length = 0.00; _height = 0.00; } public Rectangle(double L, double H) { _length = L; _height = H; } public override string Name {
273 get { return "Rectangle"; } } public override string Description() { // Get the introduction from the parent string Introduction = base.Description(); string Msg = Introduction + "\nA rectangle is a quadrilateral that has adjacent " +
"perpendicular sides. This implies that its four "
+
"angles are right."; }
return Msg;
public double Base { get { return _length; } set { _length = value; } } public double Height { get { return _height; } set { _height = value; } } public double Area { get { return Base * Height; } } public double Perimeter { get { return 2 * (Base + Height); }
274 } }
}
2. Save the file 3. To test the new properties, access the Exercise.cs file and change it as follows: using System; class Exercise { static FlatShapes.Square CreateASquare() { double side; Console.Write("Enter the side of the square: "); side = double.Parse(Console.ReadLine()); FlatShapes.Square Sqr = new FlatShapes.Square(side); return Sqr; } static void DisplaySquare(FlatShapes.Square S) { Console.WriteLine("Square Characteristics"); Console.WriteLine("Name: {0}", S.Name); Console.WriteLine("Description: {0}", S.Description()); Console.WriteLine("----------------------------"); Console.WriteLine("Side: {0}", S.Base); Console.WriteLine("Perimeter: {0}", S.Perimeter); Console.WriteLine("Area: {0}", S.Area); } static FlatShapes.Rectangle CreateARectangle() { double Len, Hgt; Console.WriteLine("Enter the dimensions of the rectangle"); Console.Write("Base: "); Len = double.Parse(Console.ReadLine()); Console.Write("Height: "); Hgt = double.Parse(Console.ReadLine()); FlatShapes.Rectangle Recto = new FlatShapes.Rectangle(Len, Hgt); return Recto; } static void DisplayRectangle(FlatShapes.Rectangle R) { Console.WriteLine("Rectangle Characteristics"); Console.WriteLine("Name: {0}", R.Name); Console.WriteLine("Description: {0}", R.Description()); Console.WriteLine("----------------------------"); Console.WriteLine("Base: {0}", R.Base); Console.WriteLine("Height: {0}", R.Height);
275
}
Console.WriteLine("Perimeter: Console.WriteLine("Area:
{0}", R.Perimeter); {0}", R.Area);
static void Main() { FlatShapes.Square Sq = new FlatShapes.Square(); FlatShapes.Rectangle Rect = new FlatShapes.Rectangle(); Sq = CreateASquare(); Rect = CreateARectangle(); Console.WriteLine("============================"); DisplaySquare(Sq); Console.WriteLine("============================"); DisplayRectangle(Rect); Console.WriteLine("============================"); Console.WriteLine(); }
}
4. To compile the project, type csc Exercise.cs Regulars.cs Quadrilaterals.cs and press Enter 5. To execute the project, type Exercise and press Enter. This would produce: Enter the side of the square: 24.55 Enter the dimensions of the rectangle Base: 32.25 Height: 26.85 ============================ Square Characteristics Name: Square Description: A quadrilateral is a geometric figure that has four sides and four angles.A square is a quadrilateral that has four equal sides and four right angl es ---------------------------Side: 24.55 Perimeter: 98.2 Area: 602.7025 ============================ Rectangle Characteristics Name: Rectangle Description: A quadrilateral is a geometric figure that has four sides and four angles. A rectangle is a quadrilateral that has adjacent perpendicular sides. This impli es that its four angles are right. ---------------------------Base: 32.25 Height: 26.85 Perimeter: 118.2 Area: 865.9125
276 ============================ 6. Return to Notepad
Previous
Copyright © 2004-2005 FunctionX, Inc.
Next
The .NET Framework and its Classes The Object Class Introduction C# was clearly created to improve on C++ and possibly offer a new alternative. To achieve this goal, Microsoft created a huge library to accompany the language. The .NET Framework is a huge library made of various classes and constants you can directly use in your C# application without necessarily explicitly loading an external library. To start, this main library of C# provides a class called Object. As you may have realized by now, every variable or function in C# (as in Java) must belong to a class, unlike C/C++ where you can have global variables or functions. Therefore, you always have to create at least one class for your application. As such, when you create a class, it automatically inherits its primary characteristics from the parent of all classes: Object.
Practical Learning: Introducing Ancestor Classes 1. Start Notepad and, in the empty file, type the following: using System; class Sport { private double _ballWeight; private int _players; private double _courtLength;
277 private double _courtWidth; public double BallWeight { get { return _ballWeight; } set { _ballWeight = value; } } public int NumberOfPlayers { get { return _players; } set { _players = value; } } public double CourtLength { get { return _courtLength; } set { _courtLength = value; } } public double CourtWidth { get { return _courtWidth; } set { _courtWidth = value; } } } class Exercise { static int Main() { Sport tennis = new Sport(); tennis.BallWeight tennis.NumberOfPlayers tennis.CourtLength tennis.CourtWidth
= = = =
57.50; 1; 23.70; 8.23;
// // // //
grams Singles galme meters meters;
Console.WriteLine("\nGame Characteristics"); Console.WriteLine("Ball Weight: {0} grams", tennis.BallWeight); Console.WriteLine("Players on each side: {0}", tennis.NumberOfPlayers); Console.WriteLine("Court Dimensions(LxW): {0}m X {1}m\n", tennis.CourtLength, tennis.CourtWidth); return 0; }
}
2. Save the file as exercise.cs in a new folder called Inherited created inside your CSharp Lessons folder
3. Open the Command Prompt and switch to the folder that contains the current exercise
4. Compile the program with csc exercise.cs 5. Execute it by typing exercise Here is an example:
278
C:\CSharp Lessons\Inherited>csc exercise.cs Microsoft (R) Visual C# .NET Compiler version 7.10.3052.4 for Microsoft (R) .NET Framework version 1.1.4322 Copyright (C) Microsoft Corporation 2001-2002. All rights reserved. C:\CSharp Lessons\Inherited>exercise Game Characteristics Ball Weight: 57.5 grams Players on each side: 1 Court Dimensions(LxW): 23.7m X 8.23m C:\CSharp Lessons\Inherited> 6. Return to Notepad
Equality of Two Class Variables When you declare and initialize two variables, one of the operations you may want to subsequently perform is to compare their value. To support this operation, the Object class provides its children with a method called Equals. The Equals() method comes in two versions. The first has the following syntax: public virtual bool Equals(object obj); This version allows you to call the Equals() method on a declared variable and pass the other variable as argument. Here is an example: using System; class BookCollection { static void Main() { // First book int NumberOfPages1 = 422; // Second book int NumberOfPages2 = 858; // Third book int NumberOfPages3 = 422; if( NumberOfPages1.Equals(NumberOfPages2) == true ) Console.WriteLine("The first and the second books have the same number of pages"); else Console.WriteLine("The first and the second books have different number of pages"); if( NumberOfPages1.Equals(NumberOfPages3) == true ) Console.WriteLine("The first and the third books have the same number of pages"); else Console.WriteLine("The first and the third books have different number of pages"); } } This would produce:
279 The first and the second books have different number of pages The first and the third books have the same number of pages The first version of the Object.Equals method is declared as virtual, which means you can override it if you create your own class. The second version of the Object.Equals() method is: public static bool Equals(object obj2, object obj2); As a static method, to use it, you can pass the variables of the two classes whose values you want to compare. In both cases, if the values of the variables are similar, the Equals() method returns true. If they are different, the method returns false. If you are using the Equals() method to compare the variables of two primitive types, the comparison should be straight forward. If you want to use this methods on variables declared from your own class, you should provide your own implementation of this method.
Practical Learning: Implementing Equality 1. To create your own implementation of the Equals() method, change the file as follows: using System; class Sport { private private private private
double int double double
_ballWeight; _players; _courtLength; _courtWidth;
public double BallWeight { get { return _ballWeight; } set { _ballWeight = value; } } public int NumberOfPlayers { get { return _players; } set { _players = value; } } public double CourtLength { get { return _courtLength; } set { _courtLength = value; } } public double CourtWidth { get { return _courtWidth; } set { _courtWidth = value; } }
280
public override int GetHashCode() { return base.GetHashCode(); } public override bool Equals(Object obj) { Sport sp = (Sport)obj; if( (_ballWeight == sp._ballWeight) && (_players == sp._players) && (_courtLength == sp._courtLength) && (_courtWidth == sp._courtWidth) ) return true; return false; }
}
class Exercise { static int Main() { Sport Euro2002 = new Sport(); Sport CAN2004 = new Sport(); Sport tennis = new Sport(); Euro2002.BallWeight Euro2002.NumberOfPlayers Euro2002.CourtLength Euro2002.CourtWidth
= = = =
435; 11; 100; 60;
// // // //
tennis.BallWeight tennis.NumberOfPlayers tennis.CourtLength tennis.CourtWidth
= = = =
57.50; 1; 23.70; 8.23;
CAN2004.BallWeight CAN2004.NumberOfPlayers CAN2004.CourtLength CAN2004.CourtWidth
= = = =
435; 11; 100; 60;
grams persons for each team meters meters
// // // //
// // // //
grams Singles game meters meters;
grams persons for each team meters meters
if( CAN2004.Equals(tennis) == true ) Console.WriteLine("The CAN2004 and the tennis variables are equal"); else Console.WriteLine("The Euro2002 and the tennis variables are not equal"); if( Euro2002.Equals(CAN2004) == true ) Console.WriteLine("The Euro2002 and CAN2004 variables are equal"); else Console.WriteLine("The Euro2002 and CAN2004 variables are not equal"); return 0;
281 } } 2. Save the file and switch to the Command Prompt 3. Compile and test the application. This would produce: The Euro2002 and the tennis variables are not equal The Euro2002 and CAN2004 variables are equal 4. Return to Notepad
Stringing a Class In previous lessons, we learned that, to convert the value of a variable declared from a primitive type to a string, you could call the ToString() function. Here is an example: using System; class BookCollection { static int Main() { int NumberOfPages = 422; }
Console.WriteLine("Number of Pages: {0}", NumberOfPages.ToString());
} In many programming languages such as C++, programmers usually have to overload an (extractor) operator to display the value(s) of class' variable to the screen. The Object class provides an alternative to this somewhat complicated solution, through the ToString() method. It syntax is: public virtual string ToString(); Although the Object class provides this method as non abstract, its implemented version is more useful if you use a primitive type such as int, double and their variances or a string variable. The best way to rely on it consists of overriding it in your own class if you desired to use its role.
Practical Learning: Converting to String 1. To implement and use a ToString() method, change the file as follows: using System; class Sport { private private private private public
double int double double
_ballWeight; _players; _courtLength; _courtWidth;
double BallWeight
282 { get { return _ballWeight; } set { _ballWeight = value; } } public int NumberOfPlayers { get { return _players; } set { _players = value; } } public double CourtLength { get { return _courtLength; } set { _courtLength = value; } } public double CourtWidth { get { return _courtWidth; } set { _courtWidth = value; } } public override int GetHashCode() { return base.GetHashCode(); } public override bool Equals(Object obj) { Sport sp = (Sport)obj; if( (_ballWeight (_players (_courtLength (_courtWidth return true;
== == == ==
sp._ballWeight) && sp._players) && sp._courtLength) && sp._courtWidth) )
return false; } public override string ToString() { string person = null; if( NumberOfPlayers.Equals(1) ) person = " person"; else person = " persons"; string result = "\nBall Weight: " + BallWeight + " grams" + "\nPlayers on each side: " + NumberOfPlayers + person + "\nCourt Dimensions(LxW): " + CourtLength + "m X " + CourtWidth + "m"; return result;
283 } } class Exercise { static int Main() { Sport CAN2004 = new Sport(); Sport tennis = new Sport(); tennis.BallWeight tennis.NumberOfPlayers tennis.CourtLength tennis.CourtWidth
= = = =
57.50; 1; 23.70; 8.23;
// // // //
grams Singles game meters meters;
CAN2004.BallWeight CAN2004.NumberOfPlayers CAN2004.CourtLength CAN2004.CourtWidth
= = = =
435; 11; 100; 60;
// // // //
grams persons for each team meters meters
Console.Write("\nCup Game Characteristics"); Console.WriteLine(CAN2004); Console.WriteLine(); Console.WriteLine("\nTennis Game Characteristics"); Console.WriteLine(tennis); return 0; }
}
2. Save the file and switch to the Command Prompt 3. Compile and test the application. This would produce: Cup Game Characteristics Ball Weight: 435 grams Players on each side: 11 persons Court Dimensions(LxW): 100m X 60m Tennis Game Characteristics Ball Weight: 57.5 grams Players on each side: 1 person Court Dimensions(LxW): 23.7m X 8.23m 4. Return to Notepad
Finalizing a Variable While a constructor, created for each class, is used to instantiate a class. The Object class provides the Finalize() method as a type of destructor.
Built-In Assemblies and Classes
284
Introduction The System namespace provides one of the largest definition of classes of the .NET Framework, but it doesn't contain everything. For example, when you start writing graphical user interface (GUI) applications, you will have to use other namespaces. The namespaces are contained in libraries called assemblies. The actual classes used in various applications are created and defined in these libraries. Before using a class, you must know the name of the assembly in which it is defined. You must also know the name of its namespace. These three pieces of information, the name of the class, the namespace in which it is defined, and the name of the assembly in which the namespace is contained, are very important. Because there are so many classes, namespaces, and libraries, the MSDN documentation is your best reference. We can only mention a few, especially those that are relevant for the subjects we are reviewing.
Microsoft Visual Basic Functions One of the strengths of Visual Basic, from its beginning, was its huge library of functions. Unfortunately, even when Visual Basic was part of the Visual Studio 6.0 environment, its functions belonged only to it and to its child languages such as VBA and VBScript. When Visual Studio .NET was created, the developers of Visual Basic added all of its valuable functions and in fact made them available to the other languages that use the .NET Framework. This means that those wonderful functions are available to use in your C# programs. The functions of Microsoft Visual Basic still belong to it and they can be called transparently in a Visual Basic application. If you want to use them in a non-Visual Basic application, you must remember to reference its library. Most (if not all) of the functions of Visual Basic are created in the Microsoft.VisualBasic.dll library but they might be in different namespaces. Based on this, you can include any Visual Basic function in your program. Here is an example: Source File: Exercise.cs using System; class Exercise { static void Main() { double Number; double Result; Console.Write("Enter a number: "); string strNbr = Console.ReadLine(); if( !Microsoft.VisualBasic.Information.IsNumeric(strNbr) ) Number = 0.00; else Number = Microsoft.VisualBasic.Conversion.Val(strNbr); Result = Number * 2; Console.WriteLine("{0} * 2 = {1}", Number, Result); }
} When compiling the program, you must reference the Microsoft.VisualBasic.dll library. Here is an example:
285 csc /reference:Microsoft.VisualBasic.dll Exercise.cs
Custom Libraries Introduction If the .NET Framework doesn't have a class you are looking for, you can create one and be able to use it over and over again in different programs. You can even create a commercial class and be able to distribute or sell it. To make this possible, you can "package" one or more classes in a library. A library is a program that contains classes and/or other resources that other programs can use. Such a program is created with the same approach as the programs we have done so far. Because a library is not an executable, it doesn't need the Main() function. A library usually has the extension .dll.
Creating a Library A library can be made of a single file or as many files as necessary. A file that is part of a library can contain one or more classes. Each class should implement a behavior that can eventually be useful and accessible to other classes. The classes in a library are created exactly like those we have used so far. Everything depends on how you compile it. To create a library, start by typing its code in a text file. Once the library is ready, to compile it, at the Command Prompt, you would type csc /target:library NameOfFile.cs and press Enter. After doing this, a library with the name of the file and the extension .dll would be created. If you want a custom name, use the following syntax: csc /target:library /out:DesiredNameOfLibrary.dll NameOfFile.cs
Practical Learning: Creating a Library 1. Start a new file in Notepad and type the following in it: using System; namespace Arithmetic { public class Operations { public static double Addition(double x, double y) { return x + y; } public static double Subtraction(double x, double y) { return x - y; } public static double Multiplication(double x, double y) { return x * y;
286 }
}
public static double Division(double x, double y) { if( y == 0 ) return 0; return x / y; }
}
2. Save the file in a new folder named Operations1 3. Save the file itself as exo.cs 4. Switch to the Command Prompt and change to the Operations1 folder
5. To create the library, type csc /target:library /out:Arithmetic.dll exo.cs and press Enter
6. Start another file in Notepad and type the following: using System; using Arithmetic; public class Exercise { static void Main() { double Number1 = 244.58; double Number2 = 5082.88; double Result = Operations.Addition(Number1, Number2); Console.WriteLine("{0} + {1} = {2}\n", Number1, Number2, Result); } }
7. Save the file in a new folder named Algebra1 8. Save the file itself as Exercise.cs 9. Switch to the Command Prompt and change to the Algebra1 folder
10. To compile the program, type csc /reference:Arithmetic.dll Exercise.cs and press Enter 11. To execute the application, type Exercise and press Enter
287
Delegates and Events Delegates Introduction The C and C++ languages have long enjoyed the concept of function pointer. This was even more useful when programming for the Microsoft Windows operating systems because the Win32 library relies on the concept of callback functions. Callback functions are used in Microsoft Windows programming to process messages. For this reason and because of their functionality, callback functions were carried out in the .NET Framework but they were defined with the name of delegate. A delegate is a special type of user-defined variable that is declared globally, like a class. In fact, a delegate is created like an interface but as a method. Based on this, a delegate provides a template for a method, like an interface provides a template for a class. Like an interface, a delegate is not defined. Its role is to show what a useful method would look like. To support this concept, a delegate can provide all the necessary information that would be used on a method. This includes a return type, no argument or one or more arguments.
Practical Learning: Introducing Delegates 1. Start Notepad and, in the empty file, type the following: using System; namespace LoanProcessing { class Exercise { static double GetPrincipal() { double P;
288 Console.Write("Enter the Principal: $"); P = double.Parse(Console.ReadLine()); return P; } static double GetInterestRate() { double r;
}
Console.Write("Enter the Interest Rate (%): "); r = double.Parse(Console.ReadLine()); return r;
static int GetPeriod() { int t; Console.Write("Enter the number of months: "); t = int.Parse(Console.ReadLine()); return t; } static int Main() { double Principal, IntRate; int NumberOfPeriods;
Console.WriteLine("This program allows you to calculate the amount of money ");
Console.WriteLine("customer will owe at the end of the lifetime of a
loan\n"); Console.WriteLine("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"); Console.WriteLine("Loan Processing\n"); Principal = GetPrincipal(); IntRate = GetInterestRate(); NumberOfPeriods= GetPeriod(); Console.WriteLine("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"); Console.WriteLine("=================================="); Console.WriteLine("Estimate on loan"); Console.WriteLine("----------------------------------"); Console.WriteLine("Principal: {0:C}", Principal); Console.WriteLine("Interest: {0:P}", IntRate / 100); Console.WriteLine("Period: {0} months", NumberOfPeriods); Console.WriteLine("==================================\n"); return 0; }
}
}
2. Save the file as Exercise.cs in a new folder called LoanProcess1 created inside your CSharp Lessons folder 3. Open the Command Prompt and switch to the folder that contains the current exercise
289 4. To compile the program, type csc /out:"Loan Evaluation".exe Exercise.cs and press Enter 5. To execute it, type "Loan Evaluation" and press Enter Here is an example: This program allows you to calculate the amount of money a customer will owe at the end of the lifetime of a loan %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Loan Processing Enter the Principal: $4500 Enter the Interest Rate (%): 12.55 Enter the number of months: 24 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ================================== Estimate on loan ---------------------------------Principal: $4,500.00 Interest: 12.55 % Period: 24 months ================================== 6. Return to Notepad 7. In the above program, the clerk was asked to provide the number of months for the period of the loan. Depending on the loan, one customer may want to specify the number of days necessary to pay the loan. Another customer may want to pay a loan over a number of years. To make this possible, we will allow the clerk to select the type of period for a loan. Change the Exercise.cs file as follows: using System; namespace LoanProcessing { class Exercise { static double GetPrincipal() { double P;
}
Console.Write("Enter the Principal: $"); P = double.Parse(Console.ReadLine()); return P;
static double GetInterestRate() { double r; Console.Write("Enter the Interest Rate (%): "); r = double.Parse(Console.ReadLine()); return r; }
290 static void GetPeriod(ref int TypeOfPeriod, ref int Periods) { Console.WriteLine("How do you want to enter the length of time?"); Console.WriteLine("1 - In Days"); Console.WriteLine("2 - In Months"); Console.WriteLine("3 - In Years"); Console.Write("Your Choice: "); TypeOfPeriod = int.Parse(Console.ReadLine());
}
if( TypeOfPeriod == 1 ) { Console.Write("Enter the number of days: "); Periods = int.Parse(Console.ReadLine()); } else if( TypeOfPeriod == 2 ) { Console.Write("Enter the number of months: "); Periods = int.Parse(Console.ReadLine()); } else if( TypeOfPeriod == 3 ) { Console.Write("Enter the number of years: "); Periods = int.Parse(Console.ReadLine()); } else { TypeOfPeriod = 0; // The user made an invalid selection. So, we will give up Console.WriteLine("Bad Selection\n"); }
static int Main() { double Principal, IntRate; int TypeOfPeriod = 0; int Periods = 0; string PeriodName = null; "); loan\n");
Console.WriteLine("This program allows you to calculate the amount of money Console.WriteLine("customer will owe at the end of the lifetime of a Console.WriteLine("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"); Console.WriteLine("Loan Processing\n"); Principal = GetPrincipal(); IntRate = GetInterestRate(); GetPeriod(ref TypeOfPeriod, ref Periods); if( TypeOfPeriod == 0 ) { // Since the user made a bad selection, stop the program here return 0; } // Since this "if" condition has a "return 0" line, if the "if" // condition produces true, the "return 0" means the function
291 // // // // //
would be terminated. If the condition is false, the inside of this "if" condition would not execute and the function would continue. This means that, if the condition is false, then the "else' is implied. Therefore, we don't have to write an "else" condition: it is automatic.
if( TypeOfPeriod == 1 ) { PeriodName = "days"; } else if( TypeOfPeriod == 2 ) { PeriodName = "months"; } else if( TypeOfPeriod == 3 ) { PeriodName = "years"; } Console.WriteLine("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"); Console.WriteLine("=================================="); Console.WriteLine("Estimate on loan"); Console.WriteLine("----------------------------------"); Console.WriteLine("Principal: {0:C}", Principal); Console.WriteLine("Interest: {0:P}", IntRate / 100); Console.WriteLine("Period: {0} {1}", Periods, PeriodName); Console.WriteLine("==================================\n"); } }
return 0;
}
8. Save the file 9. Compile and test it 10. Select the whole contents of the file (Ctrl+A) and copy it to the clipboard (Ctrl+C) 11. Start a new instance of Notepad 12. To make the program more professional, paste the file in it and change it as follows: using System; namespace LoanProcessing { class Evaluation { public double GetPrincipal() { double P;
}
Console.Write("Enter the Principal: $"); P = double.Parse(Console.ReadLine()); return P;
292
public double GetInterestRate() { double r;
}
Console.Write("Enter the Interest Rate (%): "); r = double.Parse(Console.ReadLine()); return r;
public double GetPeriod(ref int TypeOfPeriod, ref double Periods)
{
length of time?");
Console.WriteLine("How do you want to enter the Console.WriteLine("1 - In Days"); Console.WriteLine("2 - In Months"); Console.WriteLine("3 - In Years"); Console.Write("Your Choice: "); TypeOfPeriod = int.Parse(Console.ReadLine()); if( TypeOfPeriod == 1 ) { Console.Write("Enter the number of days: "); Periods = double.Parse(Console.ReadLine()); return Periods / 360; } else if( TypeOfPeriod == 2 ) { Console.Write("Enter the number of months:
");
Periods = double.Parse(Console.ReadLine()); return Periods / 12; } else if( TypeOfPeriod == 3 ) { Console.Write("Enter the number of years: "); } else {
Periods = double.Parse(Console.ReadLine()); return Periods;
TypeOfPeriod = 0; // The user made an invalid selection. So, we will give up }
Console.WriteLine("Bad Selection\n"); return 0.00;
} // Interest = Principal * rate * time in years public double InterestAmount(double P, double r, double t) { return P * (r / 100) * t; }
293 } } 13. Save the file as Evaluation.cs 14. Change the Exercise.cs file as follows: using System; namespace LoanProcessing { class Exercise { static int Main() { Evaluation Borrow = new Evaluation(); double Principal, IntRate, Period, AmountPaidAsInterest; int TypeOfPeriod = 0; double Periods = 0; string PeriodName = null; "); loan\n");
Console.WriteLine("This program allows you to calculate the amount of money Console.WriteLine("customer will owe at the end of the lifetime of a Console.WriteLine("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"); Console.WriteLine("Loan Processing\n"); Principal = Borrow.GetPrincipal(); IntRate = Borrow.GetInterestRate(); Period = Borrow.GetPeriod(ref TypeOfPeriod, ref Periods); AmountPaidAsInterest = Borrow.InterestAmount(Principal, IntRate, Period); if( TypeOfPeriod == 0 ) { // Since the user made a bad selection, stop the program here return 0; } // Since this "if" condition has a "return 0" line, if the "if" // condition produces true, the "return 0" means the function // would be terminated. If the condition is false, the inside of // this "if" condition would not execute and the function would // continue. This means that, if the condition is false, then // the "else' is implied. Therefore, we don't have to write an // "else" condition: it is automatic. if( TypeOfPeriod == 1 ) { PeriodName = "days"; } else if( TypeOfPeriod == 2 ) { PeriodName = "months"; } else if( TypeOfPeriod == 3 ) { PeriodName = "years"; }
294
Console.WriteLine("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"); Console.WriteLine("=================================="); Console.WriteLine("Estimate on loan"); Console.WriteLine("----------------------------------"); Console.WriteLine("Principal: {0:C}", Principal); Console.WriteLine("Interest: {0:P}", IntRate / 100); Console.WriteLine("Period: {0} {1}", Periods, PeriodName); Console.WriteLine("--------------------------------"); Console.WriteLine("Interest paid on Loan: {0:C}", AmountPaidAsInterest); Console.WriteLine("==================================\n"); } }
return 0;
}
15. Save the file 16. Switch to the Command Prompt
17. To compile the program, type csc /out:"Loan Evaluation".exe Evaluation.cs Exercise.cs and press Enter
18. To execute it, type "Loan Evaluation" and press Enter. Here is an example: This program allows you to calculate the amount of money a customer will owe at the end of the lifetime of a loan %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Loan Processing Enter the Principal: $850 Enter the Interest Rate (%): 14.55 How do you want to enter the length of time? 1 - In Days 2 - In Months 3 - In Years Your Choice: 1 Enter the number of days: 240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ================================== Estimate on loan ---------------------------------Principal: $850.00 Interest: 14.55 % Period: 240 days -------------------------------Interest paid on Loan: $82.45 ================================== 19. Return to the Exercise.cs file
295
Delegate Declaration To declare a delegate, you use the delegate keyword. The basic formula used to create a delegate is: [attributes] [modifiers] delegate result-type identifier ([formal-parameters]); The attributes factor can be a normal C# attribute. The modifier can be one or an appropriate combination of the following keywords: new, public, private, protected, or internal. The delegate keyword is required. The ReturnType can be any of the data types we have used so far. It can also be a type void or the name of a class. The Name must be a valid name for a method. Because a delegate is some type of a template for a method, you must use parentheses, required for every method. If this method will not take any argument, you can leave the parentheses empty. Here is an example: using System; delegate void dlgSimple(); class Exercise { static int Main() { return 0; } } After declaring a delegate, remember it only provides a template for a method, not an actual method. In order to use it, you must define a method that would carry an assignment the method is supposed to perform. That method must have the same return type and the same (number of) argument(s), if any. For example, the above declared delegate is of type void and it does not take any argument. you can define a method as follows: using System; delegate void dlgSimple(); class Exercise { private static void Welcome() { Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); } static int Main() { return 0;
296
}
} With such a method implemented, you can associate it to the name of the delegate. To do that, where you want to use the method, first declare a variable of the type of the delegate using the new operator. In the parentheses of the constructor, pass the name of the method. Here is an example
using System; delegate void dlgSimple(); class Exercise { private static void Welcome() { Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); } static int Main() { dlgSimple Announce = new dlgSimple(Welcome); }
return 0;
} This declaration gives meaning to the declared delegate. To actually use the method, call the name of the delegate as if it were a defined method. Here is an example: using System; delegate void dlgSimple(); class Exercise { private static void Welcome() { Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); } static int Main() { dlgSimple Announce = new dlgSimple(Welcome); Announce(); return 0; }
} This would produce:
Welcome to the Wonderful World of C# Programming! You can also declare a delegate that returns a value. When defining a method that would be associated with the delegate, remember that that method must return the same type of value.
297
Here is an example: using System; delegate void dlgSimple(); delegate double Addition(); class Exercise { private static void Welcome() { Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); } private static double Plus() { double a = 248.66, b = 50.28; }
return a + b;
static int Main() { dlgSimple Announce = new dlgSimple(Welcome); Addition Add = new Addition(Plus);
}
Announce(); Console.WriteLine("\n248.66 + 50.26 = {0}", Add()); return 0;
} This would produce: Welcome to the Wonderful World of C# Programming! 248.66 + 50.26 = 298.94
Practical Learning: Using a Delegate 1. To declare and use a delegate, change the Exercise.cs file as follows: using System; namespace LoanProcessing { delegate double Add2Values(double Value1, double Value2); class Exercise { static int Main() { Evaluation Borrow = new Evaluation(); double Principal, IntRate, Period, AmountPaidAsInterest;
298 int TypeOfPeriod = 0; double Periods = 0; string PeriodName = null; Add2Values Add = new Add2Values(Addition); Console.WriteLine("This program allows you to calculate the amount of money a "); Console.WriteLine("customer will owe at the end of the lifetime of a loan\n"); Console.WriteLine("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"); Console.WriteLine("Loan Processing\n"); Principal = Borrow.GetPrincipal(); IntRate = Borrow.GetInterestRate(); Period = Borrow.GetPeriod(ref TypeOfPeriod, ref Periods); AmountPaidAsInterest = Borrow.InterestAmount(Principal, IntRate, Period); double Amount = Add(Principal, AmountPaidAsInterest); if( TypeOfPeriod == 0 ) { // Since the user made a bad selection, stop the program here return 0; } // Since this "if" condition has a "return 0" line, if the "if" // condition produces true, the "return 0" means the function // would be terminated. If the condition is false, the inside of // this "if" condition would not execute and the function would // continue. This means that, if the condition is false, then // the "else' is implied. Therefore, we don't have to write an // "else" condition: it is automatic. if( TypeOfPeriod == 1 ) { PeriodName = "days"; } else if( TypeOfPeriod == 2 ) { PeriodName = "months"; } else if( TypeOfPeriod == 3 ) { PeriodName = "years"; } Console.WriteLine("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"); Console.WriteLine("=================================="); Console.WriteLine("Estimate on loan"); Console.WriteLine("----------------------------------"); Console.WriteLine("Principal: {0:C}", Principal); Console.WriteLine("Interest: {0:P}", IntRate / 100); Console.WriteLine("Period: {0} {1}", Periods, PeriodName); Console.WriteLine("--------------------------------"); Console.WriteLine("Total Amount Paid: {0:C}", Amount); Console.WriteLine("Interest paid on Loan: {0:C}", AmountPaidAsInterest); Console.WriteLine("==================================\n"); return 0;
299 }
}
static double Addition(double Value1, double Value2) { return Value1 + Value2; }
} 2. Test the program. Here is an example: This program allows you to calculate the amount of money a customer will owe at the end of the lifetime of a loan %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Loan Processing Enter the Principal: $850 Enter the Interest Rate (%): 14.55 How do you want to enter the length of time? 1 - In Days 2 - In Months 3 - In Years Your Choice: 1 Enter the number of days: 240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ================================== Estimate on loan ---------------------------------Principal: $850.00 Interest: 14.55 % Period: 240 days -------------------------------Total Amount Paid: $932.45 Interest paid on Loan: $82.45 ================================== 3. Return to the Exercise.cs file
Delegates and Classes In the above introductions, we associated delegates with only method of the main class. Because delegates are usually declared globally, that is outside of a class, they can be associated with a method of any class, provided the method has the same return type (and the same (number of) argument(s)) as the delegate. When we created the methods of the main class, we defined them as static, since all methods of the main class must be declared static. Methods of any class can also be associated to delegates. Here is an example of two methods associated with a common delegate: using System; namespace CSharpLessons {
300 delegate double Multiplication(); public class Cube { private double _side; public double Side { get { return _side; } set
{ _side = value; }
} public Cube() { _side = 0; } public Cube(double s) { _side = s; } public double Area() { return 6 * Side * Side; } public double Volume() { return Side * Side * Side; } public void CubeCharacteristics() { Multiplication AreaDefinition = new Multiplication(Area); Multiplication VolDefinition = new Multiplication(Volume);
}
Console.WriteLine("Cube Characteristics"); Console.WriteLine("Side: {0}", Side); Console.WriteLine("Area: {0}", AreaDefinition()); Console.WriteLine("Volume: {0}\n", VolDefinition());
} class Exercise { static int Main() { Cube SmallBox = new Cube(25.58); SmallBox.CubeCharacteristics(); return 0; } }
}
301
This would produce: Cube Characteristics Side: 25.58 Area: 3926.0184 Volume: 16737.925112
Delegates Compositions One of the characteristics that set delegates apart from C/C++ function pointers is that one delegate can be added to another using the + operation. This is referred to as composition. This is done by adding one delegate variable to another as in a = b + c.
Delegates and Arguments A Delegate That Takes One of More Arguments If you want to associate a method that takes arguments to a delegate, when declaring the delegate, provide the necessary argument(s) in its parentheses. Here is an example of a delegate that takes two arguments (and returns a value): delegate double Addition(double x, double y); When defining the associated method, besides returning the same type of value if not void, make sure that the method takes the same number of arguments. Here is an example: using System; delegate void dlgSimple(); delegate double Addition(double x, double y); class Exercise { private static void Welcome() { Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); } private static double Plus(double a, double b) { return a + b; } static int Main() { dlgSimple Announce = new dlgSimple(Welcome); Announce(); return 0; }
} Once again, to associate the method, declare a variable of the type of delegate and pass the name of the method to the constructor of the delegate. Here is an example:
302 Addition Add = new Addition(Plus); Notice that only the name of the method is passed to the delegate. To actually use the delegate, when calling it, in its parentheses, provide a value for the argument(s) conform to the type specified when declaring the delegate. Here is an example: using System; delegate void dlgSimple(); delegate double Addition(double x, double y); class Exercise { private static void Welcome() { Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); } private static double Plus(double a, double b) { return a + b; } static int Main() { double Value1 = 248.66, Value2 = 50.26, Result; dlgSimple Announce = new dlgSimple(Welcome); Addition Add = new Addition(Plus); Result = Add(Value1, Value2); Announce(); Console.WriteLine("\n{0} + {1} = {2}", Value1, Value2, Result); }
return 0;
} This would produce: Welcome to the Wonderful World of C# Programming! 248.66 + 50.26 = 298.92
A Delegate Passed as Argument Using delegates, one method can be indirectly passed as argument to another method. To proceed, first declare the necessary delegate. Here is a example of such a delegate: using System; namespace GeometricFormulas { public delegate double Squared(double x); public class Circle { private double _radius;
303
public double Radius { get { return _radius; } set }
{ _radius = value; }
}
} A delegate can be passed as argument to a method. Such an argument would be used as if it were a method itself. This means that, when accessed in the body of the method, the name of the delegate must be accompanied by parentheses and if the delegate takes an argument or argument, the argument(s) must be provided in the parentheses of the called delegate. Here is an example: using System; namespace GeometricFormulas { public delegate double Squared(double x); public class Circle { private double _radius; public double Radius { get { return _radius; } }
}
set
{ _radius = value; }
public double Area(Squared sqd) { return sqd(_radius) * Math.PI; }
} After declaring a delegate, remember to define a method that implements the needed behavior of that delegate. Here is an example: using System; namespace GeometricFormulas { public delegate double Squared(double x); public class Circle { private double _radius; public static double ValueTimesValue(double Value) { return Value * Value; }
304
}
} You can also define the associated method in another class, not necessarily in the class where the delegate would be needed. Once the method that implements the delegate is known, you can use the delegate as you see fit. To do that, you can declare a variable of the type of that delegate and pass the implementing method to its constructor. Here is an example:
using System; namespace GeometricFormulas { public delegate double Squared(double x); public class Circle { private double _radius; public static double ValueTimesValue(double Value) { return Value * Value; } public double Area(Squared sqd) { return sqd(_radius) * Math.PI; }
}
public void CircleCharacteristics() { Squared Sq = new Squared(ValueTimesValue); }
} This declaration gives life to the delegate and can then be used as we have proceed with delegates so far. Here is an example: using System; namespace GeometricFormulas { public delegate double Twice(double x); public delegate double Squared(double x); public class Circle { private double _radius; public static double TwoTimes(double Value) { return Value * 2; }
305
public static double ValueTimesValue(double Value) { return Value * Value; } public double Radius { get { return _radius; } }
set
{ _radius = value; }
public Circle() { _radius = 0; } public Circle(double r) { _radius = r; } public double Diameter(double rad) { return rad * 2; } public double Circumference(Twice FDiam) { double Circf; Circf = FDiam(_radius); return Circf * Math.PI; } public double Area(Squared sqd) { return sqd(_radius) * Math.PI; } public void CircleCharacteristics() { Squared Sq = new Squared(ValueTimesValue); Twice Tw = new Twice(TwoTimes); Console.WriteLine("Circle Characteristics"); Console.WriteLine("Radius: {0}", Radius); Console.WriteLine("Diameter: {0}", Diameter(_radius)); Console.WriteLine("Circumference: {0}", Circumference(Tw)); Console.WriteLine("Area: {0}\n", Area(Sq)); } } class Exercise {
306 static int Main() { Circle Round = new Circle(25.58);
} }
Round.CircleCharacteristics(); return 0;
} This would produce:
Circle Characteristics Radius: 25.58 Diameter: 51.16 Circumference: 160.723880157654 Area: 2055.65842721639
An Array of Delegates To further refine the call to a group of methods that perform the same kind of task, you can declare an array of delegates. Before creating the array, you must first know or have the methods you would be referring to. These methods must have a similar signature. This means that they must return the same type of value, they must have the same number of arguments and they must have the same type(s) of argument(s). Here are examples of such functions: class Exercise { const double PI = 3.14159; static double Diameter(double Radius) { return Radius * 2; } static double Circumference(double Radius) { return Diameter(Radius) * PI; } static double Area(double Radius) { return Radius * Radius * PI; } } To declare an array of delegates, proceed as you would for a normal C# array as we have done so far. Here is an example: using System; class Exercise { static double Diameter(double Radius) { return Radius * 2; }
307 static double Circumference(double Radius) { return Diameter(Radius) * PI; } static double Area(double Radius) { return Radius * Radius * PI; } static int Main() { Measure[] Calc = new Measure[3]; return 0; }
} You can initialize each member using its index and calling the corresponding method. This can be done as follows:
using System; delegate double Measure(double R); class Exercise { const double PI = 3.14159; static double Diameter(double Radius) { return Radius * 2; } static double Circumference(double Radius) { return Diameter(Radius) * PI; } static double Area(double Radius) { return Radius * Radius * PI; } static int Main() { double R = 12.55; Measure[] Calc = new Measure[3]; Calc[0] double D Calc[1] double C Calc[2] double A
= = = = = =
new Measure(Diameter); Calc[0](R); new Measure(Circumference); Calc[1](R); new Measure(Area); Calc[2](R);
Console.WriteLine("Circle Characteristics");
308 Console.WriteLine("Diameter: {0}", D); Console.WriteLine("Circumference: {0}", C); Console.WriteLine("Area: {0}\n", A); return 0; }
} This would produce:
Circle Characteristics Diameter: 25.1 Circumference: 78.8539 Area: 494.808
Practical Learning: Using an Array of Delegates 1. Start a new file in Notepad and type the following: using System; namespace MultipleChoiceQuestion { class Exercise { enum TMCQuestion { One, Two, Three, Four, Five }; delegate char Question(); static char Sequence() { char Answer; Console.WriteLine("Which sequence of numbers does not appear "); Console.WriteLine("to follow a recognizable order?"); Console.WriteLine("(a) 3 9 27 33"); Console.WriteLine("(b) 3 6 9 12"); Console.WriteLine("(c) 2 4 6 8"); Console.WriteLine("(d) 102 204 408 816"); Console.Write("Your Answer? "); Answer = char.Parse(Console.ReadLine()); }
return Answer;
static char Expression() { char Response; Console.WriteLine("Select the best expression to complete the empty space"); Console.WriteLine("When ... drugs to a business address, traffickers often "); Console.WriteLine("omit a recipient name"); Console.WriteLine("(a) to send"); Console.WriteLine("(b) senders"); Console.WriteLine("(c) sending"); Console.WriteLine("(d) dealing"); Console.Write("Your Answer? "); Response = char.Parse(Console.ReadLine());
309
}
return Response;
static char Sentence() { char Answer; Console.WriteLine("Even ... there are 76,000 lawyers in that city, "); Console.WriteLine("it is still a small community"); Console.WriteLine("(a) although"); Console.WriteLine("(b) though"); Console.WriteLine("(c) for"); Console.WriteLine("(d) since"); Console.Write("Your Answer? "); Answer = char.Parse(Console.ReadLine()); }
return Answer;
static char WrongWord() { char Wrong; Console.WriteLine("Select the wrong word that would complete "); Console.WriteLine("the sentence"); Console.WriteLine("For this type of business, revenue gains are ..."); Console.WriteLine("(a) limited"); Console.WriteLine("(b) scarce"); Console.WriteLine("(c) limitless"); Console.WriteLine("(d) claiming"); Console.Write("Your Answer? "); Wrong = char.Parse(Console.ReadLine()); return Wrong; } static char Right() { char Sentence; Console.WriteLine("Select the right sentence"); Console.WriteLine("(a) The company is expecting to reducing inventory,"); Console.WriteLine(" control cost, and efficiency improvement."); Console.WriteLine("(b) The company expects to reduce inventory,"); Console.WriteLine(" control cost, and improve efficiency."); Console.WriteLine("(c) The company expects to reduce inventory,"); Console.WriteLine(" control cost, and improving efficiency."); Console.WriteLine("(d) The company is expecting to reducing inventory,"); Console.WriteLine(" controlling cost, and efficiency improvement."); Console.Write("Your Answer? "); Sentence = char.Parse(Console.ReadLine()); }
return Sentence;
310 static int Main() { const int NumberOfQuestions = 5; char[] Answer = new char[NumberOfQuestions]; Question[] MCQ = new Question[NumberOfQuestions]; MCQ[0] MCQ[1] MCQ[2] MCQ[3] MCQ[4]
= = = = =
new new new new new
Question(Sequence); Question(Expression); Question(Sentence); Question(WrongWord); Question(Right);
for(int i = 0; i < NumberOfQuestions; i++) { Console.WriteLine("Question {0}", i + 1); Answer[i] = MCQ[i](); ValidateAnswer(i+1, Answer[i]); } return 0; } static void ValidateAnswer(int QstNbr, char Ans) { switch(QstNbr) { case 1: if(Ans == 'a' || Ans == 'A') Console.WriteLine("Right Answer"); else { Console.WriteLine("Wrong Answer - The right answer was 'a'"); Console.WriteLine("(a) Starting at 3, 3*3=9 and 3*9=27"); Console.WriteLine(" There is no obvious way to determine 33"); } break; case 2: if(Ans == 'c' || Ans == 'C') Console.WriteLine("Right answer"); else Console.WriteLine("Wrong Answer - The right answer was 'c'"); break; case 3:
if(Ans == 'b' || Ans == 'B') Console.WriteLine("Right answer"); else Console.WriteLine("Wrong Answer - The right answer was 'b'"); break; case 4: if(Ans == 'd' || Ans == 'D') Console.WriteLine("Right answer"); else
311 Console.WriteLine("Wrong Answer - The right answer was 'd'"); break; case 5:
if(Ans == 'b' || Ans == 'B') Console.WriteLine("Right answer"); else Console.WriteLine("Wrong Answer - The right answer was 'b'"); break; default: Console.WriteLine("Invalid Answer"); break; }
}
}
}
2. Save the file in a new folder named MCQ1 3. Save the file itself as Exercise.cs 4. At the Command Prompt, compile and execute the file
Events Introduction Except for the main class of your program (the class that contains the Main() method), every class is mostly meant to interact with other, either to request values and methods of the other classes or to provide other classes with some values or a behavior they need. When a class A requests a value or service from another class B, class A is referred to as a client of class B. This relationship is important not simply because it establishes a relationship between both classes but also because class B should be ready to provide the value or behavior that a client needs at a certain time. While a class B is asked to provide some values or methods to another class A, many things would happen. In fact, there is an order that things should follow. For example, during the lifetime of a program, that is, while a program is running, a class may be holding a value it can provide to its client but at another time, that value may not be available anymore, for any reason; nothing strange, this is just the ways it happens. Because different things can happen to a class B while a program is running, and because only class B would be aware of these, it must be able to signal to the other classes when there is a change. This is the basis of events: An event is an action that occurs on an object and affects it in a way that its clients must be made aware of. Events are mostly familiar to those who do graphical (GUI) programming as they are able to "visually" work on Windows controls and as they are able to access the objects on which actions are happening and the objects that must know when these actions occur. Still, because events are dealt with in C#, you should be aware of their functionality. Events were never part of traditional computer languages such as C/C++ or Pascal. These languages were developed without the operating system in mind. In fact, they were made platform independent so they can be used on any operating system regardless of how that OS functions. Event were highly used at the operating system level. Therefore, they were implemented in operating system libraries like Win32. On the other hands, because C# was developed a long time after its parent the C++, and
312 because it was meant to substitute Win32 knowledge, events were built in the languages. Still, all languages of the .NET Framework are "aware" of the concept of events. Although events are mostly used in Windows controls programming, they can also be implemented in console applications.
Event Creation An event is declared like a pseudo-variable but based on a delegate. Therefore, to declare an event, you must have a delegate that would implement it. Here is an example: using System; delegate void dlgSimple(); class Exercise { public static void Welcome() { Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); } } To actually declare an event, you use the event keyword with the following formula: [attributes] [modifiers] event type declarator; [attributes] [modifiers] event type member-name {accessor-declarations}; The attributes factor can be a normal C# attribute. The modifier can be one or a combination of the following keywords: public, private, protected, internal, abstract, new, override, static, virtual, or extern. The event keyword is required. It is followed by the name of the delegate that specifies its behavior. If the event is declared in the main class, it should be made static. Like everything in a program, an event must have a name. This would allow the clients to know what (particular) event occurred. Here is an example: using System; delegate void dlgSimple(); class Exercise { public static event dlgSimple Simply; public static void Welcome() { Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); } }
313
After declaring the event, you must define a method that calls the event. Here is an example: using System; delegate void dlgSimple(); class Exercise { public static event dlgSimple Simply; public static void Welcome() { Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); } public static void SayHello() { Simply(); } } When the event occurs, its delegate would be invoked. This specification is also referred to as hooking up an event. As the event occurs (or fires), the method that implements the delegate runs. This provides complete functionality for the event and makes the event ready to be used. Before using an event, you must combine it to the method that implements it. This can be done by passing the name of the method to the appropriate delegate, as we learned when studying delegates. You can then assign this variable to the event's name using the += operator. Once this is done, you can call the event. Here is an example: using System; delegate void dlgSimple(); class Exercise { public static event dlgSimple Simply; public static void Welcome() { Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); } public static void SayHello() { Simply(); } static int Main() { Simply += new dlgSimple(Welcome); SayHello(); return 0;
314 } } Instead of the += operator used when initializing the event, you can implement add and remove of the event class. Here is an example: using System; delegate void dlgSimple(); class Exercise { public event dlgSimple Simply { add { Simply += new dlgSimple(Welcome); } remove { Simply -= new dlgSimple(Welcome); } } public void Welcome() { Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); } }
Previous
Copyright © 2004-2007 FunctionX, Inc.
Exception Handling Introduction to Exceptions An Overview
Console.WriteLine("\n{0} * 2 = {1}", Number, Number * 2);
} This is a classic easy program. When it comes up, the user is asked to simply type a number. The number would then be multiplied by 2 and display the result. Imagine that a user types something that is not a valid number, such as the name of a country or somebody’s telephone number. Since this program was expecting a number and it is not prepared to multiply a string to a number, it would not know what to do. The only alternative the compiler would have is to send the problem to the operating system, hoping that the OS would know what to do. What actually happens is that, whenever the compiler is handed a task, it would try to perform the assignment. If it can’t perform the assignment, for any reason it is not prepared for, it would produce an error. As a programmer, if you can anticipate the type(s) of error(s) that could occur in your program, you can deal with it(them) by telling the compiler what to do when this type of error occurs.
Practical Learning: Introducing Exception Handling 1. Start Notepad and type the following: using System; namespace GeorgetownCleaningServices { struct OrderInformation { // Basic information about an order public string CustomerName; public string HomePhone; public DateTime OrderDate; public DateTime OrderTime; // Unsigned numbers to represent cleaning items public uint NumberOfShirts; public uint NumberOfPants; public uint NumberOfDresses; } }
2. Save the file in a new folder named GCS4
316 3. Save the file itself as OrderInfo.cs 4. To start a new file, on the main menu of Notepad, click File - rel="nofollow"> New and type the following: using System; namespace GeorgetownCleaningServices { class OrderProcessing { // Price of items const decimal PriceOneShirt const decimal PriceAPairOfPants const decimal PriceOneDress const decimal TaxRate
= = = =
0.95M; 2.95M; 4.55M; 0.0575M;
// 5.75%
OrderInformation Order; // Each private private private
of these sub totals will be used for cleaning items decimal SubTotalShirts; decimal SubTotalPants; decimal SubTotalDresses;
// Values used to process an order private decimal TotalOrder; private decimal TaxAmount; private decimal SalesTotal; private decimal AmountTended; private decimal Difference; public void ProcessOrder() { Console.WriteLine("-/- Georgetown Cleaning Services -/-"); // Request order information from the user Console.Write("Enter Customer Name: "); Order.CustomerName = Console.ReadLine(); Console.Write("Enter Customer Phone: "); Order.HomePhone = Console.ReadLine(); Console.Write("Enter the order date(mm/dd/yyyy): "); Order.OrderDate = DateTime.Parse(Console.ReadLine()); Console.Write("Enter the order time(hh:mm AM/PM): "); Order.OrderTime = DateTime.Parse(Console.ReadLine()); // Request the quantity of each category of items Console.Write("Number of Shirts: "); Order.NumberOfShirts = uint.Parse(Console.ReadLine()); Console.Write("Number of Pants: "); Order.NumberOfPants = uint.Parse(Console.ReadLine()); Console.Write("Number of Dresses: "); Order.NumberOfDresses = uint.Parse(Console.ReadLine()); // Perform the necessary calculations SubTotalShirts = Order.NumberOfShirts SubTotalPants = Order.NumberOfPants
* PriceOneShirt; * PriceAPairOfPants;
317 SubTotalDresses = Order.NumberOfDresses * PriceOneDress; // Calculate the "temporary" total of the order TotalOrder = SubTotalShirts + SubTotalPants + SubTotalDresses; // Calculate the tax amount using a constant rate TaxAmount = TotalOrder * TaxRate; // Add the tax amount to the total order SalesTotal = TotalOrder + TaxAmount; // Communicate the total to the user... Console.WriteLine("\nThe Total order is: {0:C}", SalesTotal); // and request money for the order Console.Write("Amount Tended? "); AmountTended = decimal.Parse(Console.ReadLine()); // Calculate the difference owed to the customer // or that the customer still owes to the store Difference = AmountTended - SalesTotal; }
}
ShowReceipt();
private void ShowReceipt() { Console.WriteLine(); // Display the receipt Console.WriteLine("===================================="); Console.WriteLine("-/- Georgetown Cleaning Services -/-"); Console.WriteLine("===================================="); Console.WriteLine("Customer: {0}", Order.CustomerName); Console.WriteLine("Home Phone: {0}", Order.HomePhone); Console.WriteLine("Order Date: {0:D}", Order.OrderDate); Console.WriteLine("Order Time: {0:t}", Order.OrderTime); Console.WriteLine("------------------------------------"); Console.WriteLine("Item Type Qty Unit/Price Sub-Total"); Console.WriteLine("------------------------------------"); Console.WriteLine("Shirts {0,3} {1,4} {2,6}", Order.NumberOfShirts, PriceOneShirt, SubTotalShirts); Console.WriteLine("Pants {0,3} {1,4} {2,6}", Order.NumberOfPants, PriceAPairOfPants, SubTotalPants); Console.WriteLine("Dresses {0,3} {1,4} {2,6}", Order.NumberOfDresses, PriceOneDress, SubTotalDresses); Console.WriteLine("------------------------------------"); Console.WriteLine("Total Order: {0,6}", TotalOrder.ToString("C")); Console.WriteLine("Tax Rate: {0,6}", TaxRate.ToString("P")); Console.WriteLine("Tax Amount: {0,6}", TaxAmount.ToString("C")); Console.WriteLine("Net Price: {0,6}", SalesTotal.ToString("C")); Console.WriteLine("------------------------------------"); Console.WriteLine("Amount Tended: {0,6}", AmountTended.ToString("C")); Console.WriteLine("Difference: {0,6}", Difference.ToString("C")); Console.WriteLine("===================================="); }
}
5. Save the file as OrderProcess.cs in the GCS4 folder
318 6. To start a new file, on the main menu of Notepad, click File -> New and type the following: using System; namespace GeorgetownCleaningServices { class Exercise { static void Main() { OrderProcessing Order = new OrderProcessing(); Order.ProcessOrder(); }
}
}
7. Save the file as Exercise.cs in the GCS4 folder 8. Open the Command Prompt and change to the above GCS4 directory
9. To create the application, type
csc /out:"Georgetown Cleaning Services".exe OrderInfo.cs OrderProcess.cs Exercise.cs and press Enter
10. To execute the application, type "Georgetown Cleaning Services" and press Enter. Here is an example:
-/- Georgetown Cleaning Services -/Enter Customer Name: Perl Enter Customer Phone: 301-884-0912 Enter the order date(mm/dd/yyyy): 08/04/0 Enter the order time(hh:mm AM/PM): 10:26 Number of Shirts: 12 Number of Pants: 2 Number of Dresses: 8 The Total order is: $56.79 Amount Tended? 70 ==================================== -/- Georgetown Cleaning Services -/==================================== Customer: Perl Home Phone: 301-884-0912 Order Date: Monday, August 04, 2003 Order Time: 10:26 AM -----------------------------------Item Type Qty Unit/Price Sub-Total -----------------------------------Shirts 12 0.95 11.40 Pants 2 2.95 5.90 Dresses 8 4.55 36.40 -----------------------------------Total Order: $53.70 Tax Rate: 5.75 %
319 Tax Amount: $3.09 Net Price: $56.79 -----------------------------------Amount Tended: $70.00 Difference: $13.21 ==================================== 11. Return to Notepad
Exceptional Behaviors An exception is an unusual situation that could occur in your program. As a programmer, you should anticipate any abnormal behavior that could be caused by the user entering wrong information that could otherwise lead to unpredictable results. The ability to deal with a program’s eventual abnormal behavior is called exception handling. C# provides three keywords to handle an exception.
1. Trying the normal flow: To deal with the expected behavior of a program, use the try keyword as in the following syntax: try {Behavior} The try keyword is required. It lets the compiler know that you are attempting a normal flow of your program. The actual behavior that needs to be evaluated is included between an opening curly bracket “{“ and a closing curly bracket “}”. Inside of the brackets, implement the normal flow that the program must follow, at least for this section of the code. Here is an example: using System; public class Exercise { static void Main() { double Number; try { Console.Write("Type a number: "); Number = double.Parse(Console.ReadLine()); Console.WriteLine("\n{0} * 2 = {1}", Number, Number * 2); } } }
2. Catching Errors: During the flow of the program as part of the try section, if an abnormal behavior occurs, instead of letting the program crash or instead of letting the compiler send the error to the operating system, you can transfer the flow of the program to another section that can deal with it. The syntax used by this section is: catch {WhatToDo} This section always follows the try section. There must not be any code between the try’s closing bracket and the catch section. The catch keyword is required and follows the try
320
section. Combined with the try block, the syntax of an exception would be:
try { flow } catch {
// Try the program
// Catch the exception
}
A program that includes a catch section would appear as follows:
using System; public class Exercise { static void Main() { double Number; try { Console.Write("Type a number: "); Number = double.Parse(Console.ReadLine()); Console.WriteLine("\n{0} * 2 = {1}", Number, Number * 2);
} catch { }
}
}
Practical Learning: Introducing Vague Exceptions 1. To introduce exceptions, access the OrderProcess.cs file and change it as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { . . . No Change public void ProcessOrder()
321 { . . . No Change // Request the quantity of each category of items try { Console.Write("Number of Shirts: "); Order.NumberOfShirts = uint.Parse(Console.ReadLine()); } catch { } try { Console.Write("Number of Pants: "); Order.NumberOfPants = uint.Parse(Console.ReadLine()); } catch { } try {
Console.Write("Number of Dresses: "); Order.NumberOfDresses = uint.Parse(Console.ReadLine()); } catch { } . . . No Change // and request money for the order try { Console.Write("Amount Tended? "); AmountTended = decimal.Parse(Console.ReadLine()); } catch { } // Calculate the difference owed to the customer // or that the customer still owes to the store Difference = AmountTended - SalesTotal; ShowReceipt(); } private void ShowReceipt() { . . . No Change } }
322 } 2. Save the file
3. At the Command Prompt, to compile the application, type csc /out:"Georgetown Cleaning Services".exe OrderInfo.cs OrderProcess.cs Exercise.cs and press Enter
4. To execute the application, type "Georgetown Cleaning Services" and press Enter 5. Return to Notepad
Exceptions and Custom Messages As mentioned already, if an error occurs when processing the program in the try section, the compiler transfer the processing to the next catch section. You can then use the catch section to deal with the error. At a minimum, you can display a message to inform the user. Here is an example: using System; public class Exercise { static void Main() { double Number; try { Console.Write("Type a number: "); Number = double.Parse(Console.ReadLine()); Console.WriteLine("\n{0} * 2 = {1}", Number, Number * 2); } catch { }
Console.WriteLine("There was a problem with the program");
}
} Of course, this type of message is not particularly clear but this time, the program will not crash. In the next sections, we will learn better ways of dealing with the errors and the messages.
Practical Learning: Displaying Custom Messages 1. To display custom messages to the user, change the OrderProcess.cs file as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { . . . No Change
323
public void ProcessOrder() { . . . No Change // Request the quantity of each category of items try { Console.Write("Number of Shirts: "); Order.NumberOfShirts = uint.Parse(Console.ReadLine()); } catch { Console.WriteLine("The value you typed for the number of " + "shirts is not a valid number"); } try { Console.Write("Number of Pants: "); Order.NumberOfPants = uint.Parse(Console.ReadLine()); } catch { } try { } catch {
Console.WriteLine("The value you typed for the number of " + "pair or pants is not a valid number");
Console.Write("Number of Dresses: "); Order.NumberOfDresses = uint.Parse(Console.ReadLine());
Console.WriteLine("The value you typed for the number of " + "dresses is not a valid number"); } // Perform the necessary calculations SubTotalShirts = Order.NumberOfShirts * PriceOneShirt; SubTotalPants = Order.NumberOfPants * PriceAPairOfPants; SubTotalDresses = Order.NumberOfDresses * PriceOneDress; // Calculate the "temporary" total of the order TotalOrder = SubTotalShirts + SubTotalPants + SubTotalDresses; // Calculate the tax amount using a constant rate TaxAmount = TotalOrder * TaxRate; // Add the tax amount to the total order SalesTotal = TotalOrder + TaxAmount; // Communicate the total to the user... Console.WriteLine("\nThe Total order is: {0:C}", SalesTotal); // and request money for the order try {
324
} catch {
Console.Write("Amount Tended? "); AmountTended = decimal.Parse(Console.ReadLine());
Console.WriteLine("You were asked to enter an amount of
money but..."); }
// Calculate the difference owed to the customer // or that the customer still owes to the store Difference = AmountTended - SalesTotal; }
}
ShowReceipt();
private void ShowReceipt() { . . . No Change }
} 2. Save the file
3. At the Command Prompt, to compile the application, type
csc /out:"Georgetown Cleaning Services".exe OrderInfo.cs OrderProcess.cs Exercise.cs and press Enter
4. To execute the application, type "Georgetown Cleaning Services" and press Enter. Here is an example:
-/- Georgetown Cleaning Services -/Enter Customer Name: Alexandria Enter Customer Phone: (102) 797-8382 Enter the order date(mm/dd/yyyy): 04/02/2001 Enter the order time(hh:mm AM/PM): 09:22 AM Number of Shirts: 6 Number of Pants: W The value you typed for the number of pair or pants is not a valid number Number of Dresses: 5 The Total order is: $30.09 Amount Tended? _100D You were asked to enter an amount of money but... ==================================== -/- Georgetown Cleaning Services -/==================================== Customer: Alexandria Home Phone: (102) 797-8382 Order Date: Monday, April 02, 2001 Order Time: 9:22 AM -----------------------------------Item Type Qty Unit/Price Sub-Total
325 -----------------------------------Shirts 6 0.95 5.70 Pants 0 2.95 0 Dresses 5 4.55 22.75 -----------------------------------Total Order: $28.45 Tax Rate: 5.75 % Tax Amount: $1.64 Net Price: $30.09 -----------------------------------Amount Tended: $0.00 Difference: ($30.09) ==================================== 5. Return to Notepad
Exceptions in the .NET Framework The Exception Class In traditionally-oriented error dealing languages such as C/C++ or Object Pascal, you could create any exception of your choice, including numeric or strings. To customize exception handling, you could also create your own class(es). Most libraries such as Borland's VCL and Microsoft's MFC also shipped with their own classes to handle exceptions. Event the Win32 library provides its type of mechanism to face errors. To support exception handling, the .NET Framework provides a special class called Exception. Once the compiler encounters an error, the Exception class allows you to identify the type of error and take an appropriate action. Normally, Exception mostly serves as the general class of exceptions. Anticipating various types of problems that can occur in a program, Microsoft derived various classes from Exception to make this issue friendlier. As a result, almost any type of exception you may encounter already has a class created to deal with it. Therefore, when your program faces an exception, you can easily identify the type of error. There are so many exception classes that we cannot study or review them all. The solution we will use is to introduce or review a class when we meet its type of error.
The Exception's Message In exception handling, errors are dealt with in the catch section. To do this, use catch as if it were a method. This means that, on the right side of catch, opening a parenthesis, declare a variable of the type of exception you want to deal with. By default, an exception is first of type Exception. Based on this, a typical formula to implement exception handling is: try { // Process the normal flow of the program here } catch(Exception e) { // Deal with the exception here } When an exception occurs in the try section, code compilation is transferred to the catch section. If you declare the exception as an Exception type, this class will identify the error. One of the properties of the Exception class is called Message. This property contains a string
326
that describes the type of error that occurred. You can then use this Exception.Message property to display an error message if you want. Here is an example: using System; public class Exercise { static void Main() { double Number; try {
Console.Write("Type a number: "); Number = double.Parse(Console.ReadLine());
Console.WriteLine("\n{0} * 2 = {1}", Number, Number * 2); } catch(Exception ex) { Console.WriteLine(ex.Message); } }
} Here is an example of running the program:
Type a number: 38G.25 Input string was not in a correct format.
Custom Error Messages As you can see, one of the strengths of the Exception.Message property is that it gives you a good indication of the type of problem that occurred. Sometimes, the message provided by the Exception class may not appear explicit enough. In fact, you may not want to show it to the user since, as in this case, the user may not understand what the expression "correct format" in this context means and why it is being used. As an alternative, you can create your own message and display it to the user. Here is an example: using System; public class Exercise { static void Main() { double Number = 0.00; try { Console.Write("Type a number: "); Number = double.Parse(Console.ReadLine()); Console.WriteLine("\n{0} * 2 = {1}", Number, Number * 2);
327
}
} catch(Exception ex) { Console.WriteLine("The operation could not be carried because " + "the number you typed is not valid"); }
} Here is an example of running the program: Type a number: 88D.46 The operation could not be carried because the number you typed is not valid You can also combine the Exception.Message message and your own message: using System; public class Exercise { static void Main() { double Number = 0.00; try { Console.Write("Type a number: "); Number = double.Parse(Console.ReadLine()); Console.WriteLine("\n{0} * 2 = {1}", Number, Number * 2); } catch(Exception ex) { Console.WriteLine(ex.Message + "\nThe operation could not be carried because " + "the number you typed is not valid"); } } } Here is an example of running the program: Type a number: 78m4 Input string was not in a correct format. The operation could not be carried because the number you typed is not valid
A Review of .NET Exception Classes Introduction The .NET Framework provides various classes to handle almost any type of exception you can think of. There are so many of these classes that we can only mention the few that we regularly use in our application. There are two main ways you can use one of the classes of the .NET Framework. If you know for sure that a particular exception will be produced, pass its name to the catch() clause. You don't have to name the argument. Then, in the catch() section, display a custom message. The
328
second option you have consists of using the throw keyword. We will study it later. From now on, we will try to always indicate the type of exception that could be thrown if something goes wrong in a program
FormatException When studying data formatting in Lesson 4, we saw that everything the user types into an application using the keyboard is primarily a string and that you must convert it to the appropriate type before using it. When you request a specific type of value from the user, after the user has typed it and you decide to convert it to the appropriate type, if your conversion fails, the program produces (in the next lessons, we will use he word "throw") an error. The error is of from the FormatException class. Here is a program that deals with a FormatException exception: using System; public class Exercise { static void Main() { double Number = 0.00; try {
Console.Write("Type a number: "); Number = double.Parse(Console.ReadLine());
Console.WriteLine("\n{0} * 2 = {1}", Number, Number * 2); } catch(FormatException) { Console.WriteLine("You typed an invalid number"); } }
} Here is an example of running the program:
Type a number: 39W.68g You typed an invalid number
Practical Learning: Using the FormatException Class 1. Change the OrderProcess.cs file as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { . . . No Change
329 public void ProcessOrder() { . . . No Change // Request the quantity of each category of items try { Console.Write("Number of Shirts: "); Order.NumberOfShirts = uint.Parse(Console.ReadLine()); } catch(FormatException) { Console.WriteLine("The value you typed for the number of " + "shirts is not a valid number"); } try {
Console.Write("Number of Pants: "); Order.NumberOfPants = uint.Parse(Console.ReadLine());
} catch(FormatException) { Console.WriteLine("The value you typed for the number of " + "pair or pants is not a valid number"); } try { Console.Write("Number of Dresses: "); Order.NumberOfDresses = uint.Parse(Console.ReadLine()); } catch(FormatException) { Console.WriteLine("The value you typed for the number of " + "dresses is not a valid number"); } . . . No Change // Communicate the total to the user... Console.WriteLine("\nThe Total order is: {0:C}", SalesTotal); // and request money for the order try { Console.Write("Amount Tended? "); AmountTended = decimal.Parse(Console.ReadLine()); } catch(FormatException) { Console.WriteLine("You were asked to enter an amount of money but..."); } // Calculate the difference owed to the customer // or that the customer still owes to the store Difference = AmountTended - SalesTotal;
330
}
ShowReceipt();
private void ShowReceipt() { . . . No Change }
} } 2. Save the file
3. At the Command Prompt, to compile the application, type
csc /out:"Georgetown Cleaning Services".exe OrderInfo.cs OrderProcess.cs Exercise.cs and press Enter
4. To execute the application, type "Georgetown Cleaning Services" and press Enter 5. Return to Notepad
The OverflowException Exception A computer application receives, processes, and produces values on a regular basis as the program is running. To better manage these values, as we saw when studying variables and data types in Lesson 2, the compiler uses appropriate amounts of space to store its values. It is not unusual that either you the programmer or a user of your application provides an value that is beyond the allowed range based on the data type. For example, we saw that a byte uses 8 bits to store a value and a combination of 8 bits can store a number no more than 255. If you provide a value higher than 255 to be stored in a byte, you get an error. Consider the following program: using System; // An Exercise class class Exercise { static void Main() { byte NumberOfPages; Console.Write("Enter the number of pages of the newspaper: "); NumberOfPages = byte.Parse(Console.ReadLine()); Console.WriteLine("Number of Pages of the Newspaper: {0}\n", NumberOfPages); } } When a value beyond the allowable range is asked to be stored in memory, the compiler produces (the verb is "throws" as we will learn soon) an error of the OverflowException class. Here is an example of running the program: Enter the number of pages of the newspaper: 824 Unhandled Exception: System.OverflowException: Value was either too large or too small for an unsigned byte. at System.Byte.Parse(String s, NumberStyles style, IFormatProvider provider)
331
11
at System.Byte.Parse(String s) at Exercise.Main() in c:\programs\msvcs .net 2003\project17\exercise.cs:line
As with the other errors, when this exception is thrown, you should take appropriate action.
ArgumentOutOfRangeException Once again, when studying the techniques of converting or formatting values in Lesson 4, we saw that a value is passed to the Parse() method of its data type for analysis. For a primitive data type, the Parse() method scans the string and if the string cannot be converted into a valid character or number, the compiler usually throws a FormatException exception as we saw above. Other classes such as DateTime also use a Parse() method to scan the value submitted to it. For example, if you request a date value from the user, the DateTime.Parse() method scans the string to validate it. In US English, Parse() expects the user to type a string in the form m/d/yy or mm/dd/yy or mm/dd/yyyy. Consider the following program: using System; // An Exercise class class Exercise { static void Main() { DateTime DateHired; Console.Write("Enter Date Hired: "); DateHired = DateTime.Parse(Console.ReadLine()); }
Console.WriteLine("Date Hired: {0:d}\n", DateHired);
} If the user types a value that cannot be converted into a valid date, the compiler throws an ArgumentOutOfRangeException exception. Here is an example of running the above program: Enter Date Hired: 1244/04/258 Unhandled Exception: System.FormatException: String was not recognized as a valid DateTime. at System.DateTimeParse.Lex(Int32 dps, __DTString str, DateTimeToken dtok, DateTimeRawInfo raw, DateTimeResult result, DateTimeFormatInfo& dtfi) at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles) at System.DateTime.Parse(String s, IFormatProvider provider, DateTimeStyles styles) at System.DateTime.Parse(String s, IFormatProvider provider) at System.DateTime.Parse(String s) at Exercise.Main() in c:\programs\msvcs .net 2003\project17\exercise.cs:line 11 One way you can avoid this is to guide the user but still take appropriate actions, just in case this error is thrown.
332
Practical Learning: Using an ArgumentOutOfRangeException Exception 1. Change the OrderProcess.cs file as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { . . . No Change
public void ProcessOrder() { Console.WriteLine("-/- Georgetown Cleaning Services -/-"); // Request order information from the user Console.Write("Enter Customer Name: "); Order.CustomerName = Console.ReadLine(); Console.Write("Enter Customer Phone: "); Order.HomePhone = Console.ReadLine(); try { Console.WriteLine("Enter the date this order was placed"); Console.Write("Enter Today's Day: "); int day = int.Parse(Console.ReadLine()); Console.Write("Enter Current Month: "); int month = int.Parse(Console.ReadLine()); Console.Write("Enter This Year: "); int year = int.Parse(Console.ReadLine()); Order.OrderDate = new DateTime(year, month, day); } catch(ArgumentOutOfRangeException) { Console.WriteLine("The date you entered is not valid - We will igno it");
} try {
ignore it");
Console.WriteLine("Enter the time this order was placed"); Console.Write("Enter the hour: "); int hour = int.Parse(Console.ReadLine()); Console.Write("Enter the minutes: "); int minute = int.Parse(Console.ReadLine()); Order.OrderDate = new DateTime(0, 0, 0, hour, minute, 0);
} catch(ArgumentOutOfRangeException) { Console.WriteLine("The time value you entered is not valid - We wil } // Request the quantity of each category of items try
333 { Console.Write("Number of Shirts: "); Order.NumberOfShirts = uint.Parse(Console.ReadLine()); } catch(FormatException) { Console.WriteLine("The value you typed for the number of " + "shirts is not a valid number"); } try {
Console.Write("Number of Pants: "); Order.NumberOfPants = uint.Parse(Console.ReadLine());
} catch(FormatException) { Console.WriteLine("The value you typed for the number of " + "pair or pants is not a valid number"); } try { Console.Write("Number of Dresses: "); Order.NumberOfDresses = uint.Parse(Console.ReadLine()); } catch(FormatException) { Console.WriteLine("The value you typed for the number of " + "dresses is not a valid number"); } . . . No Change
// Communicate the total to the user... Console.WriteLine("\nThe Total order is: {0:C}", SalesTotal); // and request money for the order try { Console.Write("Amount Tended? "); AmountTended = decimal.Parse(Console.ReadLine()); } catch(FormatException) { Console.WriteLine("You were asked to enter an amount of money but.. } // Calculate the difference owed to the customer // or that the customer still owes to the store Difference = AmountTended - SalesTotal; }
ShowReceipt();
private void ShowReceipt() {
334 . . . No Change }
}
} 2. Save the file
3. At the Command Prompt, to compile the application, type
csc /out:"Georgetown Cleaning Services".exe OrderInfo.cs OrderProcess.cs Exercise.cs and press Enter
4. To execute the application, type "Georgetown Cleaning Services" and press Enter. Here is an example:
-/- Georgetown Cleaning Services -/Enter Customer Name: Gertrude Ngana Enter Customer Phone: 208-923-8263 Enter the date this order was placed Enter Today's Day: 48 Enter Current Month: 6 Enter This Year: 2002 The date you entered is not valid - We will ignore it Enter the time this order was placed Enter the hour: 62 Enter the minutes: 380 The time value you entered is not valid - We will ignore it Number of Shirts: w The value you typed for the number of shirts is not a valid number Number of Pants: 8 Number of Dresses: 2 The Total order is: $34.58 Amount Tended? q42 You were asked to enter an amount of money but... ==================================== -/- Georgetown Cleaning Services -/==================================== Customer: Gertrude Ngana Home Phone: 208-923-8263 Order Date: Monday, January 01, 0001 Order Time: 12:00 AM -----------------------------------Item Type Qty Unit/Price Sub-Total -----------------------------------Shirts 0 0.95 0 Pants 8 2.95 23.60 Dresses 2 4.55 9.10 -----------------------------------Total Order: $32.70 Tax Rate: 5.75 % Tax Amount: $1.88 Net Price: $34.58 -----------------------------------Amount Tended: $0.00 Difference: ($34.58)
335 ==================================== 5. Return to Notepad
The DivideByZeroException Exception Division by zero is an operation to always avoid. It is so important that it is one of the most fundamental exceptions of the computer. It is addressed at the core level even by the Intel and AMD processors. It is also addressed by the operating systems at their level. It is also addressed by most, if not all, compilers. It is also addressed by most, if not, all libraries. This means that this exception is never welcomed anywhere. The .NET Framework also provides it own class to face this operation. If an attempt to divide a value by 0, the compiler throws a DivideByZeroException exception. We will see an example later.
Techniques of Using Exceptions Throwing an Exception As mentioned above, the Exception class is equipped with a Message property that carried a message for the error that occurred. We also mentioned that the message of this property may not be particularly useful to a user. Fortunately, you can create your own message and pass it to the Exception. To be able to receive custom messages, the Exception class provides the following constructor: public Exception(string message); To use it, in the section that you are anticipating the error, type the throw keyword followed by a new instance of the Exception class using the constructor that takes a string. Here is an example: using System; class Exercise { static void Main() { double Operand1, Operand2; double Result = 0.00; char Operator; two numbers");
Console.WriteLine("This program allows you to perform an operation on try {
a number:");
Console.WriteLine("To proceed, enter a number, an operator, and Operand1 = double.Parse(Console.ReadLine()); Operator = char.Parse(Console.ReadLine()); Operand2 = double.Parse(Console.ReadLine()); if( Operator != '+' && Operator != '-' && Operator != '*' &&
Operator != '/')
throw new Exception(Operator.ToString());
336
switch(Operator) { case '+': Result = Operand1 + Operand2; break; case '-': Result = Operand1 - Operand2; break; case '*': Result = Operand1 * Operand2; break; case '/': Result = Operand1 / Operand2; break; default: Console.WriteLine("Bad Operation"); break; } Console.WriteLine("\n{0} {1} {2} = {3}", Operand1, Operator, Operand2, Result); } catch(Exception ex) { Console.WriteLine("\nOperation Error: {0} is not a valid operator", ex.Message); } } } Here is an example of running the program: This program allows you to perform an operation on two numbers To proceed, enter a number, an operator, and a number: 38.44 # 124.52 Operation Error: # is not a valid operator
Catching Various Exceptions In the examples above, when we anticipated some type of problem, we instructed the compiler to use our default catch section. We left it up to the compiler to find out when there was a problem and we provided a catch section to deal with it. A method with numerous or complex operations and requests can also produce different types of errors. With such a type of program, you should be able to face different problems and deal with them individually, each by its own kind. To do this, you can create different catch sections, each made for a particular error. The formula used would be: try {
// Code to Try
337 } catch(Arg1) { // One Exception } catch(Arg2) { // Another Exception } The compiler would proceed in a top-down:
1. Following the normal flow of the program, the compiler enters the try block 2. If no exception occurs in the try block, the rest of the try block is executed
If an exception occurs in the try block, the compiler registers the type of error that occurred. If there is a throw line, the compiler registers it also:
a. The compiler gets out of the try section b. The compiler examines the first catch. If the first catch matches the thrown error, that catch executes and the exception handling routine may seize. If the first catch doesn’t match the thrown error, the compiler proceeds with the next catch
c. The compiler checks the next match, if any and proceeds as in the first match. This continues until the compiler finds a catch that matches the thrown error
d. If one of the catches matches the thrown error, its body executes. If no catch matches the thrown error, the compiler calls the Exception class and uses the default message Multiple catches are written if or when a try block is expected to throw different types of errors. Once again, consider the following program: using System; class Exercise { static void Main() { double Operand1, Operand2; double Result = 0.00; char Operator; Console.WriteLine("This program allows you to perform an operation on two numbers"); try { a number:");
Console.WriteLine("To proceed, enter a number, an operator, and Operand1 = double.Parse(Console.ReadLine()); Operator = char.Parse(Console.ReadLine()); Operand2 = double.Parse(Console.ReadLine()); switch(Operator) { case '+':
338 Result = Operand1 + Operand2; break; case '-': Result = Operand1 - Operand2; break; case '*': Result = Operand1 * Operand2; break; case '/': Result = Operand1 / Operand2; break; default: Console.WriteLine("Bad Operation"); break; } Console.WriteLine("\n{0} {1} {2} = {3}", Operand1, Operator, Operand2, Result); } catch(Exception ex) { Console.WriteLine("\nOperation Error: {0} is not a valid operator", ex.Message); } } } This program works fine as long as the user types a valid sequence of values made of a number, a valid arithmetic operator, and a number. Anything else, such an invalid number, an unexpected operator, or a wrong sequence (such as a number then another number instead of an operator), would cause an error to be thrown. Obviously various bad things could happen when this program is running. To handle the exceptions that this program could produce, you can start with the most likely problem that would occur. Trusting that a user is able to provide the two numbers that are requested, it is possible that a user would type an invalid operator. For example, for this program we will perform only the addition (+), the subtraction(-), the multiplication(*), and the division(/). Therefore, we will first validate the operator. This can be done as follows: using System; class Exercise { static void Main() { double Operand1, Operand2; double Result = 0.00; char Operator; Console.WriteLine("This program allows you to perform an operation on two numbers"); try {
339
a number:");
Console.WriteLine("To proceed, enter a number, an operator, and Operand1 = double.Parse(Console.ReadLine()); Operator = char.Parse(Console.ReadLine()); Operand2 = double.Parse(Console.ReadLine());
Operator != '/')
if( Operator != '+' && Operator != '-' && Operator != '*' && throw new Exception(Operator.ToString()); switch(Operator) { case '+': Result = Operand1 + Operand2; break; case '-': Result = Operand1 - Operand2; break; case '*': Result = Operand1 * Operand2; break; case '/': Result = Operand1 / Operand2; break; default: Console.WriteLine("Bad Operation"); break;
} Console.WriteLine("\n{0} {1} {2} = {3}", Operand1, Operator,
Operand2, Result); } catch(Exception ex) { Console.WriteLine("\nOperation Error: {0} is not a valid operator", ex.Message); } } }
When this program runs, if the user provides a valid number followed by a wrong operator, we call the Exception(string message) constructor and pass it a string converted from the character that was typed. Then, when the compiler gets out of the try block, it looks for and finds a catch clause that receives a character value. Therefore, this catch is executed. Imagine that the user wants to perform a division. You need to tell the compiler what to do if the user enters the denominator as 0 (or 0.00). If this happens, the best option, and probably the only one you should consider is to display a message and get out. Fortunately, the .NET Framework provides the DivideByZeroException class to deal with an exception caused by division by zero. As done with the message passed to the Exception class, you can compose your own message and pass it to the DivideByZeroException(string message) constructor. Exception is the parent of all exception classes. This corresponds to the three periods of a C+
340
+' catch(...) block. Therefore, if you write various catch blocks, the one that takes the Exception as argument must be the last. Here is an example that catches two types of exceptions: using System; class Exercise { static void Main() { double Operand1, Operand2; double Result = 0.00; char Operator; Console.WriteLine("This program allows you to perform an operation on two numbers"); try { a number:");
Console.WriteLine("To proceed, enter a number, an operator, and Operand1 = double.Parse(Console.ReadLine()); Operator = char.Parse(Console.ReadLine()); Operand2 = double.Parse(Console.ReadLine());
Operator != '/')
if( Operator != '+' && Operator != '-' && Operator != '*' && throw new Exception(Operator.ToString());
is not allowed");
if( Operator == '/' ) if( Operand2 == 0 ) throw new DivideByZeroException("Division by zero switch(Operator) { case '+': Result = Operand1 + Operand2; break; case '-': Result = Operand1 - Operand2; break; case '*': Result = Operand1 * Operand2; break; case '/': Result = Operand1 / Operand2; break; default: Console.WriteLine("Bad Operation"); break;
341 } Console.WriteLine("\n{0} {1} {2} = {3}", Operand1, Operator, Operand2, Result); } catch(DivideByZeroException ex) { Console.WriteLine(ex.Message); } catch(Exception ex) { Console.WriteLine("\nOperation Error: {0} is not a valid operator", ex.Message); } } } When running this program, if the user types a wrong operator, the compiler gets out the try block and looks for a catch that takes an Exception as argument. It finds the second and executes it. If the user enters the right values (a number, an operator, and another number), then the compiler finds out if the operator entered was a forward slash “/” used to perform a division. If the user wants to perform a division, the compiler finds out if the second operand, the denominator, is 0. If it is, we create a DivideByZeroException instance and pass our own message to it. Based on this exception, the compiler gets out of the try block and starts looking for a catch block that takes a DivideByZeroException argument. It finds it in the first catch. Therefore, the compiler executes it.
Practical Learning: Identifying the Thrown Exception 1. To catch various exceptions, change the OrderProcess.cs file as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { . . . No Change public void ProcessOrder() { Console.WriteLine("-/- Georgetown Cleaning Services -/-"); // Request order information from the user Console.Write("Enter Customer Name: "); Order.CustomerName = Console.ReadLine(); Console.Write("Enter Customer Phone: "); Order.HomePhone = Console.ReadLine(); the date
// To make it easy for the user, we will request different values for try { Console.WriteLine("Enter the date this order was placed"); Console.Write("Enter Today's Day: "); int day = int.Parse(Console.ReadLine());
342 Console.Write("Enter Current Month: "); int month = int.Parse(Console.ReadLine()); Console.Write("Enter This Year: "); int year = int.Parse(Console.ReadLine()); Order.OrderDate = new DateTime(year, month, day); } // This exception is thrown if the user types a value that cannot // be converted into a valid number catch(FormatException ex) { Console.WriteLine("Error: " + ex.Message + "\nThe value you entered " + "is not a valid number"); } // This exception is thrown if the values that user had typed cannot // produce a valid date value catch(ArgumentOutOfRangeException ex) { Console.WriteLine("The date you entered is not valid - " + "We will ignore it and use 1/1/0001 instead"); } try { Console.Write("Enter the time the order was placed(hh:mm AM/PM): "); Order.OrderTime = DateTime.Parse(Console.ReadLine()); } // This exception is thrown if the user typed values that cannot // produce a valid (date or) time value catch(FormatException) { Console.WriteLine("The time you entered is not valid and it will be refused"); } // Request the quantity of each category of items try { Console.Write("Number of Shirts: "); Order.NumberOfShirts = uint.Parse(Console.ReadLine()); } // This exception is thrown if the user typed a value that cannot // be recognized as a valid number catch(FormatException ex) { Console.WriteLine("Error: " + ex.Message + "\nThe value you typed for the number of " + "shirts is not valid"); } // This exception is thrown if the user types a negative value catch(OverflowException) { Console.WriteLine("The number you typed is negative but " + "we cannot accept a negative number of shirts"); } try
343 { Console.Write("Number of Pants: "); Order.NumberOfPants = uint.Parse(Console.ReadLine()); } // This exception is thrown if the user typed a value that cannot // be recognized as a valid number catch(FormatException ex) { Console.WriteLine("Error: " + ex.Message + "\nThe value you typed for the number of " + "pair or pants is not valid"); } // This exception is thrown if the user types a negative value catch(OverflowException) { Console.WriteLine("The number you typed is negative and " + "we cannot accept it"); } try { Console.Write("Number of Dresses: "); Order.NumberOfDresses = uint.Parse(Console.ReadLine()); } // This exception is thrown if the user typed a value that cannot // be recognized as a valid number catch(FormatException ex) { Console.WriteLine("Error: " + ex.Message + "\nThe value you typed for the number of " + "dresses is not valid"); } // This exception is thrown if the user types a negative value catch(OverflowException) { Console.WriteLine("The number you typed is lower than the " + "acceptable number. It will be ignored"); } // Perform the necessary calculations . . . No Change }
} } 2. Save the file
ShowReceipt();
private void ShowReceipt() { . . . No Change }
344 3. At the Command Prompt, to compile the application, type csc /out:"Georgetown Cleaning Services".exe OrderInfo.cs OrderProcess.cs Exercise.cs and press Enter
4. To execute the application, type "Georgetown Cleaning Services" and press Enter. Here is an example: -/- Georgetown Cleaning Services -/Enter Customer Name: Andrew Palermo Enter Customer Phone: (240) 493-8935 Enter the date this order was placed Enter Today's Day: 12 Enter Current Month: 08 Enter This Year: 2002 Enter the time the order was placed(hh:mm AM/PM): 12:98 The value you entered is not a valid number Number of Shirts: 9 Number of Pants: -5 The number you typed is negative and we cannot accept it Number of Dresses: -12 The number you typed is lower than the acceptable number. It will be ignored The Total order is: $9.04 Amount Tended? W10.00F Error: Input string was not in a correct format. You were asked to enter an amount of money but you typed an invalid currency val ue ==================================== -/- Georgetown Cleaning Services -/==================================== Customer: Andrew Palermo Home Phone: (240) 493-8935 Order Date: Monday, August 12, 2002 Order Time: 12:00 AM -----------------------------------Item Type Qty Unit/Price Sub-Total -----------------------------------Shirts 9 0.95 8.55 Pants 0 2.95 0 Dresses 0 4.55 0 -----------------------------------Total Order: $8.55 Tax Rate: 5.75 % Tax Amount: $0.49 Net Price: $9.04 -----------------------------------Amount Tended: $0.00 Difference: ($9.04) ==================================== 5. Return to Notepad
Exceptions Nesting
345
The calculator simulator we have studied so far performs a division as one of its assignments. We learned that, in order to perform any operation, the compiler must first make sure that the user has entered a valid operator. Provided the operator is one of those we are expecting, we also must make sure that the user typed valid numbers. Even if these two criteria are met, it was possible that the user enter 0 for the denominator. The block that is used to check for a non-zero denominator depends on the exception that validates the operators. The exception that could result from a zero denominator depends on the user first entering a valid number for the denominator. You can create an exception inside of another. This is referred to as nesting an exception. This is done by applying the same techniques we used to nest conditional statements. This means that you can write an exception that depends on, and is subject to, another exception. To nest an exception, write a try block in the body of the parent exception. The nested try block must be followed by its own catch(es) clause. To effectively handle the exception, make sure you include an appropriate throw in the try block. Here is an example: using System; class Exercise { static void Main() { double Operand1, Operand2; double Result = 0.00; char Operator; two numbers");
Console.WriteLine("This program allows you to perform an operation on try {
a number:");
Console.WriteLine("To proceed, enter a number, an operator, and Operand1 = double.Parse(Console.ReadLine()); Operator = char.Parse(Console.ReadLine()); Operand2 = double.Parse(Console.ReadLine()); if( Operator != '+' && Operator != '-' && Operator != '*' &&
Operator != '/')
throw new Exception(Operator.ToString()); switch(Operator) { case '+': Result = Operand1 + Operand2; Console.WriteLine("\n{0} + {1} = {2}", Operand1,
Operand2, Result);
break; case '-': Result = Operand1 - Operand2; Console.WriteLine("\n{0} - {1} = {2}", Operand1,
Operand2, Result);
break;
346
Operand2, Result);
case '*': Result = Operand1 * Operand2; Console.WriteLine("\n{0} * {1} = {2}", Operand1, break; case '/': // The following exception is nested in the
previous try
try {
if(Operand2 == 0) throw new DivideByZeroException("Division by zero is not allowed"); Result = Operand1 / Operand2; Console.WriteLine("\n{0} / {1} = {2}",
Operand1, Operand2, Result);
} catch(DivideByZeroException ex) { Console.WriteLine(ex.Message); } break; } } catch(Exception ex) { Console.WriteLine("\nOperation Error: {0} is not a valid operator", ex.Message); } } } Here is an example of running the program: This program allows you to perform an operation on two numbers To proceed, enter a number, an operator, and a number: 245.55 / 0 Division by zero is not allowed
Practical Learning: Nesting Exceptions 1. To nest exceptions, change the OrderProcess.cs file as follows: using System; namespace GeorgetownCleaningServices { class OrderProcessing { // Price of items const decimal PriceOneShirt = 0.95M; const decimal PriceAPairOfPants = 2.95M; const decimal PriceOneDress = 4.55M;
347 const decimal TaxRate
= 0.0575M;
// 5.75%
OrderInformation Order; // Each private private private
of these sub totals will be used for cleaning items decimal SubTotalShirts; decimal SubTotalPants; decimal SubTotalDresses;
// Values used to process an order private decimal TotalOrder; private decimal TaxAmount; private decimal SalesTotal; private decimal AmountTended; private decimal Difference; public void ProcessOrder() { Console.WriteLine("-/- Georgetown Cleaning Services -/-"); // Request order information from the user Console.Write("Enter Customer Name: "); Order.CustomerName = Console.ReadLine(); Console.Write("Enter Customer Phone: "); Order.HomePhone = Console.ReadLine();
// To make it easy for the user, we will request different values for the d try { int month = DateTime.Today.Month; int day = DateTime.Today.Day; int year = DateTime.Today.Year; Console.WriteLine("Enter the date this order was placed"); try {
Console.Write("Enter the year this order was placed: "); year = int.Parse(Console.ReadLine()); if( year < 1998 ) throw new ArgumentOutOfRangeException("This business "Any year prior to that value is inv if( year > DateTime.Today.Year ) throw new ArgumentOutOfRangeException("Common... " + "We can't process an order that will
} // Exception to deal with if the user typed a non-digit in the valu catch(FormatException ex) { Console.WriteLine("Error: " + ex.Message + "\nYou entered an invalid value for the year } // Exception to deal with if the user typed a negative number catch(ArgumentOutOfRangeException ex) { Console.WriteLine(ex.Message); }
348
to 12");
// Evaluate the value of the month try { Console.Write("Enter the month this order was placed: "); month = int.Parse(Console.ReadLine()); if( month < 1 ) throw new ArgumentOutOfRangeException("A negative mo if( month > 12 ) throw new ArgumentOutOfRangeException("Valid numbers
} // Exception to deal with if the user typed a non-digit in the valu catch(FormatException ex) { Console.WriteLine("Error: " + ex.Message + "\nYou entered an invalid value for the month"); } // Exception to deal with if the user typed a negative numb catch(ArgumentOutOfRangeException ex) { Console.WriteLine(ex.Message); }
// Evaluate the value of the day try { Console.Write("Enter the day this order was placed: "); day = int.Parse(Console.ReadLine()); if( day < 0 ) throw new ArgumentOutOfRangeException("A negative da } // Exception to deal with if the user typed a non-digit in the valu catch(FormatException ex) { Console.WriteLine("Error: " + ex.Message + "\nYou entered an invalid value"); } // Exception to deal with if the user typed a negative number catch(ArgumentOutOfRangeException ex) { Console.WriteLine(ex.Message); } Order.OrderDate = new DateTime(year, month, day); } // This exception is thrown if the user types a value that cannot // be converted into a valid number catch(FormatException ex) { Console.WriteLine("Error: " + ex.Message + "\nThe value you entered " + "is not a valid number"); }
349 . . . No Change ShowReceipt(); } private void ShowReceipt() { . . . No Change } }
}
2. At the Command Prompt, to compile the application, type
csc /out:"Georgetown Cleaning Services".exe OrderInfo.cs OrderProcess.cs Exercise.cs and press Enter
3. To execute the application, type "Georgetown Cleaning Services" and press Enter
Exceptions and Methods One of the most effective techniques used to deal with code is to isolate assignments. We have learned this when studying methods of classes. For example, the switch statement that was performing the operations in the “normal” version of our program can be written as follows: using System; class Exercise { static void Main() { double Number1, Number2; double Result = 0.00; char Operator; two numbers");
Console.WriteLine("This program allows you to perform an operation on try {
Console.WriteLine("To proceed, enter"); Console.Write("First Number: "); Number1 = double.Parse(Console.ReadLine()); Console.Write("An Operator (+, -, * or /): "); Operator = char.Parse(Console.ReadLine()); if( Operator != '+' && Operator != '-' && Operator != '*' && Operator != '/' ) throw new Exception(Operator.ToString()); Console.Write("Second Number: "); Number2 = double.Parse(Console.ReadLine()); if( Operator == '/' ) if( Number2 == 0 ) throw new DivideByZeroException("Division by zero
is not allowed");
350
Result = Calculator(Number1, Number2, Operator); Console.WriteLine("\n{0} {1} {2} = {3}", Number1, Operator,
Number2, Result); } catch(FormatException) { Console.WriteLine("The number you typed is not valid"); } catch(DivideByZeroException ex) { Console.WriteLine(ex.Message); } catch(Exception ex) { Console.WriteLine("\nOperation Error: {0} is not a valid operator", ex.Message); } } static double Calculator(double Value1, double Value2, char Symbol) { double Result = 0.00; switch(Symbol) { case '+': Result = Value1 + Value2; break; case '-': Result = Value1 - Value2; break; case '*': Result = Value1 * Value2; break;
}
case '/': Result = Value1 / Value2; break;
return Result; }
} You can still use regular methods along with methods that handle exceptions. As done in the Main() function, any method of a program can take care of its own exceptions that would occur in its body. Here is an example of an exception handled in a function:
using System; class Exercise { static void Main() {
351 double Number1, Number2; double Result = 0.00; char Operator; two numbers");
Console.WriteLine("This program allows you to perform an operation on try {
Console.WriteLine("To proceed, enter"); Console.Write("First Number: "); Number1 = double.Parse(Console.ReadLine()); Console.Write("An Operator (+, -, * or /): "); Operator = char.Parse(Console.ReadLine()); if( Operator != '+' && Operator != '-' && Operator != '*' && Operator != '/' ) throw new Exception(Operator.ToString()); Console.Write("Second Number: "); Number2 = double.Parse(Console.ReadLine());
Result = Calculator(Number1, Number2, Operator); } catch(FormatException) { Console.WriteLine("The number you typed is not valid"); } catch(Exception ex) { Console.WriteLine("\nOperation Error: {0} is not a valid operator", ex.Message); } } static double Calculator(double Value1, double Value2, char Symbol) { double Result = 0.00;
Result);
switch(Symbol) { case '+': Result = Value1 + Value2; Console.WriteLine("\n{0} + {1} = {2}", Value1, Value2, break;
Result);
case '-': Result = Value1 - Value2; Console.WriteLine("\n{0} - {1} = {2}", Value1, Value2, break; case '*': Result = Value1 * Value2;
352 Console.WriteLine("\n{0} * {1} = {2}", Value1, Value2,
Result);
break; case '/': // The following exception is nested in the previous try try { if(Value2 == 0) throw new DivideByZeroException("Division by zero is not allowed"); Result = Value1 / Value2; Console.WriteLine("\n{0} / {1} = {2}", Value1, Value2, Result);
} catch(DivideByZeroException ex) { Console.WriteLine(ex.Message); } break;
} return Result; }
} Isolating assignments and handing them to functions is a complete and important matter in the area of application programming. Consider a program that handles a simple exception such as this one:
using System; class Exercise { static void Main() { double Number1, Number2; double Result = 0.00; char Operator = '/'; Console.WriteLine("This program allows you to perform a division of two numbers"); try { Console.WriteLine("To proceed, enter two numbers:"); Number1 = double.Parse(Console.ReadLine()); Number2 = double.Parse(Console.ReadLine());; if( Number2 == 0 ) throw new DivideByZeroException("Division by zero is not allowed"); Result = Number1 / Number2; Console.WriteLine("\n{0} / {1} = {2}", Number1, Number2, Result);
353
}
} catch(DivideByZeroException ex) { Console.WriteLine(ex.Message); }
} One of the ways you can use methods in exception routines is to have a central method that receives variables, and sends them to an external method. The external method tests the value of a variable. If an exception occurs, the external method displays or sends a throw. This throw can be picked up by the method that sent the error. Observe the following example that implements this scenario: using System; class Exercise { static void Main() { double Number1, Number2; numbers");
Console.WriteLine("This program allows you to perform a division of two try {
}
Console.WriteLine("To proceed, enter two numbers:"); Number1 = double.Parse(Console.ReadLine()); Number2 = double.Parse(Console.ReadLine());;
Division(Number1, Number2); } catch(DivideByZeroException ex) { Console.WriteLine(ex.Message); }
static void Division(double a, double b) { double Result; // If an exception occurred, if( b == 0 ) // then throw a string to the function caller throw new DivideByZeroException("Division by zero is not allowed"); Result = a / b; Console.WriteLine("\n{0} / {1} = {2}", a, b, Result); }
} In this program, the Division method receives two values that it is asked to perform a division with. The Division method analyzes the second argument that represents the denominator. If this argument is zero, an exception is found and the Division method throws a
354
DivideByZeroException exception. A method can also be called to perform more than one test to eventually throw more than one exception. Such a method can (and should) be programmed to throw different types of exceptions.
Previous
Copyright © 2004-2007 FunctionX, Inc.
Next
Introduction to Arrays A Series of Similar Items Introduction Imagine you want to create a program that would use a series of numbers. In math, we represent such a series as follows: X1, X2, X3, X4, X5. You can also represent a list of items as follows: Alex Gaston Hermine Jerry In C#, so far, to use a series of items, we were declaring a variable for each of them. If the list was made of numbers, we would declare variables for such numbers as follows: using System; namespace CSharpLessons { class Exercise { static void Main() { double number1 = 12.44,
355
} }
number2 = 525.38, number3 = 6.28, number4 = 2448.32, number5 = 632.04;
} Instead of using individual variables that share the same characteristics, you can group them in an entity like a regular variable but called an array. Therefore, an array is a series of items of the same kind. It could be a group of numbers, a group of cars, a group of words, etc but all items of the array must be of the same type.
Practical Learning: Introducing Arrays 1. Start Notepad 2. In the empty file, type the following: using System; class IceCream { public const decimal BasePrice
= 1.55M;
public void ProcessAnOrder() { int dFlv = 0, dCont = 0, dIngrd = 0; int Scoops; decimal PriceIngredient, TotalPrice; Console.WriteLine("Ice Cream Vendor Machine"); do {
try {
Console.WriteLine("What type of flavor do you want?"); Console.WriteLine("1 - "); Console.WriteLine("2 - "); Console.WriteLine("3 - "); Console.WriteLine("4 - "); Console.WriteLine("5 - "); Console.WriteLine("6 - "); Console.Write("Your Choice? " ); dFlv = int.Parse(Console.ReadLine());
} catch(FormatException) { Console.WriteLine("You must enter a valid number and no other character!");
}
356 if( dFlv < 1 || dFlv > 6 ) Console.WriteLine("Invalid Choice - Try Again!\n"); } while( dFlv < 1 || dFlv > 6 ); do {
try {
Console.WriteLine("What type of container do you want?"); Console.WriteLine("1 - "); Console.WriteLine("2 - "); Console.WriteLine("3 - "); Console.Write("Your Choice? "); dCont = int.Parse(Console.ReadLine());
} catch(FormatException) { Console.WriteLine("You must enter a valid number and no other
character!");
} if( dCont < 1 || dCont > 3 ) Console.WriteLine("Invalid Choice - Try Again!"); } while( dCont < 1 || dCont > 3 ); do { try { Console.WriteLine("Do you want an ingredient or not"); Console.WriteLine("1 - "); Console.WriteLine("2 - "); Console.WriteLine("3 - "); Console.WriteLine("4 -
1. Console.WriteLine("4 - ");
Console.Write("Your Choice? "); dIngrd = int.Parse(Console.ReadLine());
} catch(FormatException) { Console.WriteLine("You must enter a valid number and no other
character!");
} if( dIngrd < 1 || dIngrd > 4 ) Console.WriteLine("Invalid Choice - Try Again!"); } while( dIngrd < 1 || dIngrd > 4 ); do {
357 try {
Console.Write("How many scoops(1, 2, or 3)? "); Scoops = int.Parse(Console.ReadLine());
} catch(FormatException) { Console.WriteLine("You must enter a valid number and no other
character!");
} if( Scoops < 1 || Scoops > 3 ) Console.WriteLine("Invalid Choice - Try Again!"); } while( Scoops < 1 || Scoops > 3 ); if( dIngrd == 2 || dIngrd == 3 || dIngrd == 4 ) PriceIngredient = 0.65M; else PriceIngredient = 0.00M; TotalPrice = (BasePrice * Scoops) + PriceIngredient; DisplayReceipt(dFlv, dCont, dIngrd, Scoops, TotalPrice); } public void DisplayReceipt(int Flv, int Cont, int Ingrd, int spoons, decimal TotalPrice) { Console.WriteLine("\nIce Cream Order");
}
Console.WriteLine("Scoops: {0}", spoons); Console.WriteLine("Total Price: {0:C}\n", TotalPrice);
}
2. Save the file in a new folder named IceCream2 3. Save the file itself as Order.cs in the IceSream2 folder 4. Start another instance of Notepad and type the following: using System; class Exercise { static void Main() { } }
5. Save the file as Exercise.cs in the IceCream2 folder
Array Creation Before creating an array, you must first decide the type its items will be made of. Is it a group of numbers, a group of chairs, a group of buttons on a remote controls? This information allows the compiler to know how much space each item of the group will require. This is because each item
358
of the group will occupy its own memory space, just like any of the variables we have used so far. After deciding about the type of data of the items that make up the series, you must use a common name to identify them. The name is simply the same type you would use for a variable as we have used so far. The name allows you and the compiler to identify the area in memory where the items are located. Thirdly, you must specify the number of items that will constitute the group. For the compiler to be able to allocate an adequate amount of space for the items of the list, once it knows how much space each item will require, it needs to know the number of items so an appropriate and large enough amount of space can be reserved. The number of items of an array is included in square brackets, as in [5]. In C# (unlike some other languages like C/C++ or Pascal), an array is considered a reference type. Therefore, an array requests its memory using the new operator (like a pointer in C/C++). Based on this, the basic formula to declare an array is: DataType[] VariableName = new DataType[Number]; In this formula, the DataType factor can be one of the types we have used so far. It can also be the name of a class. The square brackets on the left of the assignment operator are used to let the compiler know that you are declaring an array instead of a regular variable. The new operator allows the compiler to reserve memory in the heap. The Number factor is used to specify the number of items of the list. Based on the above formula, here is an example of an array variable: using System; namespace CSharpLessons { class Exercise { static void Main() { double[] number = new double[5]; Console.WriteLine(); }
}
}
Practical Learning: Creating an Array 1. To create arrays, access the Order.cs file and change it as follows: using System; class IceCream { public const decimal BasePrice public void ProcessAnOrder() {
= 1.55M;
359 int dFlv = 0, dCont = 0, dIngrd = 0; int Scoops = 0; decimal PriceIngredient, TotalPrice; string[] Flavor = new string[6]; string[] Container = new string[3]; string[] Ingredient = new string[4]; Console.WriteLine("Ice Cream Vendor Machine"); . . . No Change } . . . No Change } 2. Save the file
Operations on Arrays Array Initialization When creating an array, you can specify the number of items that make up its list. Each item of the series is referred to as a member of the array. Once the array has been created, each one of its members is initialized with a 0 value. Most, if not all, of the time, you will need to change the value of each member to a value of your choice. This is referred to as initializing the array. An array is primarily a variable; it is simply meant to carry more than one value. Like every other variable, an array can be initialized. There are two main techniques you can use to initialize an array. If you have declared an array as done above, to initialize it, you can access each one of its members and assign it a desired but appropriate value. In math, if you create a series of values as X1, X2, X3, X4, and X5, each member of this series can be identified by its subscript number. In this case the subscripts are 1, 2, 3, 4, and 5. This subscript number is also called an index. In the case of an array also, each member of an array can be referred to by an incremental number called an index. A C# (like a C/C++) array is zerobased. This means that the first member of the series has an index of 0, the second has an index of 1. In math, the series would be represented as X0, X1, X2, X3, and X4. In C#, the index of a member of an array is written in its own square brackets. This is the notation you would use to locate each member. One of the actions you can take would consist of assigning it a value. Here is an example: using System; namespace CSharpLessons { class Exercise { static void Main() { double[] number = new double[5]; number[0] = 12.44;
360 number[1] = 525.38; number[2] = 6.28; number[3] = 2448.32; number[4] = 632.04; Console.WriteLine(); }
}
} Besides this technique, you can also initialize the array as a whole when declaring it. To do this, on the right side of the declaration, before the closing semi-colon, type the values of the array members between curly brackets and separated by a comma. Here is an example: using System; namespace CSharpLessons { class Exercise { static void Main() { double[] number = new double[5]{ 12.44, 525.38, 6.28, 2448.32, 632.04 }; Console.WriteLine();
} }
} If you use this second technique, you don't have to specify the number of items in the series. If you can leave all square brackets empty:
using System; namespace CSharpLessons { class Exercise { static void Main() { double[] number = new double[]{ 12.44, 525.38, 6.28, 2448.32, 632.04 }; Console.WriteLine(); }
}
} If you leave the square brackets empty, the compiler will figure out the number of items.
Practical Learning: Using the Members of an Array 1. To initialize arrays and use their members, change the Order.cs file as follows: using System; class IceCream
361 { public const decimal BasePrice
= 1.55M;
public void ProcessAnOrder() { int dFlv = 0, dCont = 0, dIngrd = 0; int Scoops = 0; decimal PriceIngredient, TotalPrice; string[] Flavor = new string[6]{ "Vanilla", "Cream of Cocoa", "Organic Strawberry", "Butter Pecan", "Cherry Coke", "Chocolate Brownies" }; string[] Container = new string[3]; Container[0] = "Cone"; Container[1] = "Cup"; Container[2] = "Bowl"; string[] Ingredient = new string[]{"No Ingredient", "Peanuts", "M & M", "Cookies" }; Console.WriteLine("Ice Cream Vendor Machine"); do {
try {
Console.WriteLine("What type of flavor do you want?"); Console.WriteLine("1 - {0}", Flavor[0]); Console.WriteLine("2 - {0}", Flavor[1]); Console.WriteLine("3 - {0}", Flavor[2]); Console.WriteLine("4 - {0}", Flavor[3]); Console.WriteLine("5 - {0}", Flavor[4]); Console.WriteLine("6 - {0}", Flavor[5]); Console.Write("Your Choice? " ); dFlv = int.Parse(Console.ReadLine());
} catch(FormatException) { Console.WriteLine("You must enter a valid number and no other character!");
} if( dFlv < 1 || dFlv > 6 ) Console.WriteLine("Invalid Choice - Try Again!\n"); } while( dFlv < 1 || dFlv > 6 ); do {
362 try {
Console.WriteLine("What type of container do you want?"); Console.WriteLine("1 - {0}", Container[0]); Console.WriteLine("2 - {0}", Container[1]); Console.WriteLine("3 - {0}", Container[2]); Console.Write("Your Choice? "); dCont = int.Parse(Console.ReadLine());
} catch(FormatException) { Console.WriteLine("You must enter a valid number and no other
character!");
} if( dCont < 1 || dCont > 3 ) Console.WriteLine("Invalid Choice - Try Again!"); } while( dCont < 1 || dCont > 3 ); do { try { Console.WriteLine("Do you want an ingredient or not"); Console.WriteLine("1 - {0}", Ingredient[0]); Console.WriteLine("2 - {0}", Ingredient[1]); Console.WriteLine("3 - {0}", Ingredient[2]); Console.WriteLine("4 - {0}", Ingredient[3]); Console.Write("Your Choice? "); dIngrd = int.Parse(Console.ReadLine());
} catch(FormatException) { Console.WriteLine("You must enter a valid number and no other
character!");
} if( dIngrd < 1 || dIngrd > 4 ) Console.WriteLine("Invalid Choice - Try Again!"); } while( dIngrd < 1 || dIngrd > 4 ); do { try { Console.Write("How many scoops(1, 2, or 3)? "); Scoops = int.Parse(Console.ReadLine()); } catch(FormatException) { Console.WriteLine("You must enter a valid number and no other character!"); } if( Scoops < 1 || Scoops > 3 ) Console.WriteLine("Invalid Choice - Try Again!"); } while( Scoops < 1 || Scoops > 3 );
363
if( dIngrd == 2 || dIngrd == 3 || dIngrd == 4 ) PriceIngredient = 0.65M; else PriceIngredient = 0.00M; TotalPrice = (BasePrice * Scoops) + PriceIngredient; DisplayReceipt(dFlv, dCont, dIngrd, Scoops, TotalPrice); } public void DisplayReceipt(int Flv, int Cont, int Ingrd, int spoons, decimal TotalPrice) { Console.WriteLine("\nIce Cream Order"); switch(Flv) { case 2: Console.WriteLine("Flavor: Cream of Cocoa"); break; case 3: Console.WriteLine("Flavor: Organic Strawberry"); break; case 4: Console.WriteLine("Flavor: Butter Pecan"); break; case 5: Console.WriteLine("Flavor: Cherry Coke"); break; case 6: Console.WriteLine("Flavor: Chocolate Brownies"); break; default: Console.WriteLine("Flavor: Vavilla"); break; } switch(Cont) { case 2: case 3:
}
Console.WriteLine("Container: break;
Console.WriteLine("Container: break; default: Console.WriteLine("Container: break;
Cup"); Bowl"); Cone");
switch(Ingrd) { case 2: Console.WriteLine("Ingredient: break; case 3:
Peanuts");
364
case 4:
}
}
Console.WriteLine("Ingredient: break;
Console.WriteLine("Ingredient: break; default: Console.WriteLine("Ingredient: break;
M & M"); Cookies"); None");
Console.WriteLine("Scoops: {0}", spoons); Console.WriteLine("Total Price: {0:C}\n", TotalPrice);
} 2. Save the Order.cs file 3. To test the IceCream class, access the Exercise.cs file and change it as follows: using System; class Exercise { static void Main() { IceCream IS = new IceCream(); }
IS.ProcessAnOrder();
} 4. Save the Exercise.cs file 5. To test the application, open the Command Prompt and change to the folder in which you created the C# file
6. Type csc Order.cs Exercise.cs and press Enter 7. After compiling, type Exercise to execute and press Enter. Here is an example: Ice Cream Vendor Machine What type of flavor do you want? 1 - Vanilla 2 - Cream of Cocoa 3 - Organic Strawberry 4 - Butter Pecan 5 - Cherry Coke 6 - Chocolate Brownies Your Choice? 8 Invalid Choice - Try Again! What type of flavor do you want? 1 - Vanilla 2 - Cream of Cocoa 3 - Organic Strawb
365
Techniques of Using Arrays Main()'s Argument Introduction
366
When a program starts, it looks for an entry point as the area of entrance. This is the role of the Main() function. In fact, a program, that is an executable program, starts by, and stops with, the Main() function. The way this works is that, at the beginning, the compiler enters he Main() function in a top-down approach, starting just after the opening curly bracket. If it finds a problem and judges that it is not worth continuing, it stops and lets you know. If, or as long as, it doesn't find a problem, it continues line after line, with the option to even call or execute a method in the same file or in another file. This process continues to the closing curly bracket "}". Once the compiler finds the closing bracket, the whole program has ended and stops. If you want the user to provide additional information when executing your program, you can take care of this in the Main() function as this is the entry point of your program.
Practical Learning: Introducing the Command Line 1. In Notepad, start a new empty file and type the following: using System; namespace CSharpLessons { class Exercise { static int Main() { string FirstName = "James"; string LastName = "Weinberg"; double WeeklyHours = 36.50; double HourlySalary = 12.58; string FullName = LastName + ", " + FirstName; double WeeklySalary = WeeklyHours * HourlySalary; Console.WriteLine("Employee Payroll"); Console.WriteLine("Full Name: {0}", FullName); Console.WriteLine("WeeklySalary: {0}", WeeklySalary.ToString("C")); return 0; }
}
}
2. Save the file in a new folder named CommandLine1 3. Save the file itself as Exercise.cs in the CommandLine1 folder 4. To test the application, open the Command Prompt and change to the folder in which you created the C# file
5. Type csc Exercise.cs and press Enter 6. To execute the program, type the name Exercise and press Enter. This would produce: C:\CSharp Lessons\CommandLine1>csc Exercise.cs
367 Microsoft (R) Visual C# .NET Compiler version 7.10.3052.4 for Microsoft (R) .NET Framework version 1.1.4322 Copyright (C) Microsoft Corporation 2001-2002. All rights reserved. C:\CSharp Lessons\CommandLine1>Exercise Employee Payroll Full Name: Weinberg, James WeeklySalary: $459.17 C:\CSharp Lessons\CommandLine1> 7. Return to your text editor
Command Request from Main() So far, to compile a program, we simply typed the csc command at the command prompt. Then, to execute a program, we typed its name at the prompt. If we distributed one of these programs, we would tell the user to type the name of the program at the command prompt. In some cases, you may want the user to type additional information besides the name of the program. To request additional information from the user, pass a string argument to the Main() function. The argument should be passed as an array and make sure you provide a name for the argument. Here is an example: using System; class ObjectName { static int Main(string[] args) { return 0; } } The reason you pass the argument as an array is so you can use as many values as you judge necessary. To provide values at the command prompt, the user types the name of the program followed by each necessary value. Here is an example:
368
The values the user considering the name stored at index 0, the args[0], the second is
would provide are stored in the zero-based argument array without of the program. The first value (that is, after the name of the program) is second at index 1, etc. Based on this, the first argument is represented by represented by args[1], etc.
Since the array argument (like all C# arrays) is based on the Array class of the System namespace, if you want to find out how many values the user supplied, you can call the Array.Length property. Each of the values the user types is a string. If any one of them is not a string, you should/must convert its string first to the appropriate value.
Practical Learning: Passing an Argument to Main() 1. To pass an argument to Main(), change the file as follows: using System; namespace CSharpLessons { class Exercise { static int Main(string[] Argument) { string FirstName; string LastName; Double WeeklyHours; Double HourlySalary; FirstName = Argument[0]; LastName = Argument[1]; WeeklyHours = Double.Parse(Argument[2]); HourlySalary = Double.Parse(Argument[3]);
369 string FullName = LastName + ", " + FirstName; Double WeeklySalary = WeeklyHours * HourlySalary; Console.WriteLine("Employee Payroll"); Console.WriteLine("Full Name: {0}", FullName); Console.WriteLine("WeeklySalary: {0}", WeeklySalary.ToString("C")); } }
return 0;
}
2. Save the file and switch to the command prompt
3. To compile the application, type csc Exercise.cs and press Enter 4. To execute the program, type Exercise followed by a first name, a last name, and two decimal values. An example would be Exercise Catherine Engolo 42.50 20.48
5. Return to your text editor
Two-Dimensional Arrays Introduction The arrays we used so far were made of a uniform series, where all members constituted a simple list, like a column of names on a piece of paper. Also, all items fit in one list. In some cases, you may want to divide the list in delimited sections. For example, if you create a list of names, you may want part of the list to include family members and another part of the list to include friends. Instead of creating a second list, you can add a second dimension to the list. In other words, you would like to create a list of a list, or one list inside of another list, although the list is still made of items with common characteristics. A multi-dimensional array is a series of lists so that each list contains its own list. For example, if you create two lists of names, you would have an array of two lists. Each array or list would have its own list or array.
Practical Learning: Introducing Multidimensional Arrays 1. Start a new file in Notepad and type the following:
370 using System; class DepartmentStore { static int Main() { long ItemID = 0; string Description = "Unknown"; decimal Price = 0.00M; Console.WriteLine("Receipt"); Console.WriteLine("Item Number: {0}", ItemID); Console.WriteLine("Description: {0}", Description); Console.WriteLine("Unit Price: {0:C}\n", Price); }
return 0;
}
2. Save the file in a new folder named DeptStore4 3. Save the file as Exercise.cs 4. Open the Command Prompt and change to the above DeptStore4
5. Compile the exercise with csc Exercise.cs and execute it with Exercise This would produce:
Receipt Item Number: 0 Description: Unknown Unit Price: $0.00 6. Return to Notepad
Creation of a Two-Dimensional Array The most basic multi-dimensional array is an array of an array, also referred to as twodimensional. To create a two-dimensional array, declare the array variable as we did earlier but add a comma in the square brackets. The formula you would use is: DataType[,] VariableName; The pair of brackets is empty but must contain a comma. There are two ways you can use a twodimensional array. If you are declaring the array variable but are not ready to initialize it, use the following formula: DataType[,] VariableName = new DataType[Number1,Number2]; Based on this, type two integers separated by a comma in the right square brackets. Here is an example: using System; namespace CSharpLessons { class Exercise {
371 static void Main() { string[,] Members = new string[2,4]; } } In this declaration, the Members variable contains two lists. Each of the two lists contains 4 items. This means that the first list contains 4 items, the second list contains 4 items also. Therefore, the whole list is made of 8 items (2*4=8). Because the variable is declared as a string, each of the 8 items is a string. You can initialize an array variable when declaring it. To do this, on the right side of the declaration, before the closing semi-colon, type an opening and a closing curly brackets. Inside of the brackets, include a pair of an opening and a closing curly brackets for each internal list of the array. Then, inside of a pair of curly brackets, provide a list of the values of the internal array, just as you would do for a one-dimensional array. Here is an example: using System; namespace CSharpLessons { class Exercise { static void Main() { String[,] members = new String[2,4]{ {"Celeste", "Mathurin", "Alex", "Germain"}, {"Jeremy", "Mathew", "Anselme", "Frederique"} }; Console.WriteLine(); }
} If you use this technique to initialize an array, you can omit specifying the dimension of the array.
Practical Learning: Creating a Two-Dimensional Array 1. To create and use a two-dimensional array, change the file as follows: using System; class DepartmentStore { static int Main() { // The first list contains women's items // The other contains non-women items long[,] ItemNumber = new long[2,5]{ { 947783, 934687, 973947, 987598, 974937 }, { 739579, 367583, 743937, 437657, 467945 } }; string[,] ItemName = new string[2,5]{ { "Women Double-faced wool coat", "Women Floral Silk Tank Blouse", "Women Push Up Bra",
372 "Women Chiffon Blouse", "Women Bow Belt Skirtsuit" }, { "Men Cotton Polo Shirt", "Children Cable-knit Sweater ", "Children Bear Coverall Cotton", "Baby three-piece Set ", "Girls Jeans with Heart Belt " } }; decimal[,] UnitPrice = new decimal[2,5]{ { 275.25M, 180.05M, 50.00M, 265.35M, 245.55M }, { 45.55M, 25.65M, 28.25M, 48.55M, 19.95M } }; long ItemID = 0; string Description = "Unknown"; decimal Price = 0.00M; Console.WriteLine("Receipt"); Console.WriteLine("Item Number: {0}", ItemID); Console.WriteLine("Description: {0}", Description); Console.WriteLine("Unit Price: {0:C}\n", Price); }
return 0;
} 2. Save the file
Access to Members of a Two-Dimensional Array To use the members of a two-dimensional array, you can access each item individually. For example, to initialize a two-dimensional array, you can access each member of the array and assign it a value. The external list is zero-based. In other words, the first list has an index of 0, the second list has an index of 1. Internally, each list is zero-based and behaves exactly like a one-dimensional array. To access a member of the list, type the name of the variable followed by its square brackets. In the brackets, type the index of the list, a comma, and the internal index of the member whose access you need. Here is an example: using System; namespace CSharpLessons { class Exercise { static void Main() { String[,] members = new String[2,4]; members[0,0] = "Celeste"; members[0,1] = "Mathurin"; members[0,2] = "Alex"; members[0,3] = "Germain"; members[1,0] = "Jeremy"; members[1,1] = "Mathew"; members[1,2] = "Anselme"; members[1,3] = "Frederique"; Console.WriteLine(); }
}
373
Practical Learning: Accessing Members of a Two-Dimensional Array 1. To retrieve the values of a two-dimensional array, change the file as follows: using System; class DepartmentStore { static int Main() { // The first list contains women's items // The other contains non-women items long[,] ItemNumber = new long[2,5]{ { 947783, 934687, 973947, 987598, 974937 }, { 739579, 367583, 743937, 437657, 467945 } }; string[,] ItemName = new string[2,5]{ { "Women Double-faced wool coat ", "Women Floral Silk Tank Blouse", "Women Push Up Bra", "Women Chiffon Blouse", "Women Bow Belt Skirtsuit" }, { "Men Cotton Polo Shirt", "Children Cable-knit Sweater", "Children Bear Coverall Cotton", "Baby three-piece Set", "Girls Jeans with Heart Belt" } }; decimal[,] UnitPrice = new decimal[2,5]{ { 275.25M, 180.05M, 50.00M, 265.35M, 245.55M }, { 45.55M, 25.65M, 28.25M, 48.55M, 19.95M } }; long ItemID = 0; string Description = "Unknown"; decimal Price = 0.00M; // Order Processing try { Console.Write("Enter Item Number: "); ItemID = long.Parse(Console.ReadLine()); } catch(FormatException) { Console.WriteLine("Invalid Number - The program will terminate\n"); } for(int i = 0; i < 2; i++) { for(int j = 0; j < 5; j++) { if( ItemID == ItemNumber[i,j] ) { Description = ItemName[i,j]; Price = UnitPrice[i,j]; } } } Console.WriteLine("Receipt");
374 Console.WriteLine("Item Number: {0}", ItemID); Console.WriteLine("Description: {0}", Description); Console.WriteLine("Unit Price: {0:C}\n", Price); return 0; }
}
2. Save, compile, and execute the application. Here is an example: Enter Item Number: 397494 Receipt Item Number: 397494 Description: Unknown Unit Price: $0.00 3. Here is another example of executing the application: Enter Item Number: 367583 Receipt Item Number: 367583 Description: Children Cable-knit Sweater Unit Price: $25.65 4. Return to Notepad
Multidimensional Arrays Introduction Beyond two dimensions, you can create a variable that represents various lists and each list contains various internal lists. This is referred to as a multidimensional array.
Creation of a Multidimensional Array To create a mutidimensional array, add as many commas in the square brackets as you judge them necessary. Here is an example of a three-dimensional array initialized: using System; namespace CSharpLessons { class Exercise { static void Main() { double[,,] number = new double[2,3,5]{ { { 2448.32, 632.04}, 762.48,
{-378.05,
83.02},
386.73} }, 526.82,1704.62},
12.44, 525.38,
{
64.92, { {
-7.44,
-6.28,
48.14, 634.18, 86.74,
48.02, 120.44,
-534.60, 38.62,
375
128.48}, 408.62} },
{
56.85, 105.48, 363.31,
172.62,
{
906.68, 47.12,-166.07,
4444.26,
}; Console.WriteLine("Number of items {0}", number.Length); Console.WriteLine("Number of items {0}", number.Rank); Console.WriteLine(); }
}
In this example, we are creating 2 groups of items. Each of the two groups is made of three lists. Each list contains 5 numbers. This would produce: Number of items 30 Number of items 3
Access to Members of a Multidimensional Array To locate each member of a multidimensional array, type the name of the array followed by the opening square bracket, followed by the 0-based first dimension, followed by a comma. Continue with each dimension and end with the closing square bracket. Here is an example: using System; namespace CSharpLessons { class Exercise { static void Main() { double[,,] number = new double[2,3,5]{ { { 2448.32, 632.04}, 762.48,
83.02},
{
386.73} }, {
128.48}, 408.62} },
{
{-378.05,
64.92, { {
526.82,1704.62},
12.44, 525.38,
-7.44,
-6.28,
48.14, 634.18, 86.74,
48.02, 120.44,
-534.60,
38.62,
56.85, 105.48, 363.31, 906.68, 47.12,-166.07,
172.62, 4444.26,
}; Console.WriteLine("Number[0][0][0] Console.WriteLine("Number[0][0][1] Console.WriteLine("Number[0][0][2] Console.WriteLine("Number[0][0][3] Console.WriteLine("Number[0][0][4]
= = = = =
{0}", number[0,0,0]); {0}", number[0,0,1]); {0}", number[0,0,2]); {0}", number[0,0,3]); {0}\n", number[0,0,4]);
Console.WriteLine("Number[0][1][0] = {0}", number[0,1,0]); Console.WriteLine("Number[0][1][1] = {0}", number[0,1,1]); Console.WriteLine("Number[0][1][2] = {0}", number[0,1,2]); Console.WriteLine("Number[0][1][3] = {0}", number[0,1,3]); Console.WriteLine("Number[0][1][4] = {0}\n", number[0,1,4]);
376
Console.WriteLine("Number[0][2][0] = {0}", number[0,2,0]); Console.WriteLine("Number[0][2][1] = {0}", number[0,2,1]); Console.WriteLine("Number[0][2][2] = {0}", number[0,2,2]); Console.WriteLine("Number[0][2][3] = {0}", number[0,2,3]); Console.WriteLine("Number[0][2][4] = {0}\n", number[0,2,4]); Console.WriteLine("Number[1][0][0] Console.WriteLine("Number[1][0][1] Console.WriteLine("Number[1][0][2] Console.WriteLine("Number[1][0][3] Console.WriteLine("Number[1][0][4]
= = = = =
{0}", number[1,0,0]); {0}", number[1,0,1]); {0}", number[1,0,2]); {0}", number[1,0,3]); {0}\n", number[1,0,4]);
Console.WriteLine("Number[1][1][0] = {0}", number[1,1,0]); Console.WriteLine("Number[1][1][1] = {0}", number[1,1,1]); Console.WriteLine("Number[1][1][2] = {0}", number[1,1,2]); Console.WriteLine("Number[1][1][3] = {0}", number[1,1,3]); Console.WriteLine("Number[1][1][4] = {0}\n", number[1,1,4]); Console.WriteLine("Number[1][2][0] = {0}", number[1,2,0]); Console.WriteLine("Number[1][2][1] = {0}", number[1,2,1]); Console.WriteLine("Number[1][2][2] = {0}", number[1,2,2]); Console.WriteLine("Number[1][2][3] = {0}", number[1,2,3]); Console.WriteLine("Number[1][2][4] = {0}\n", number[1,2,4]); Console.WriteLine("Number of items {0}", number.Length); Console.WriteLine("Number of items {0}", number.Rank); }
Console.WriteLine();
} This would produce: Number[0][0][0] Number[0][0][1] Number[0][0][2] Number[0][0][3] Number[0][0][4]
= = = = =
12.44 525.38 -6.28 2448.32 632.04
Number[0][1][0] Number[0][1][1] Number[0][1][2] Number[0][1][3] Number[0][1][4]
= = = = =
-378.05 48.14 634.18 762.48 83.02
Number[0][2][0] Number[0][2][1] Number[0][2][2] Number[0][2][3] Number[0][2][4]
= = = = =
64.92 -7.44 86.74 -534.6 386.73
Number[1][0][0] Number[1][0][1] Number[1][0][2] Number[1][0][3] Number[1][0][4]
= = = = =
48.02 120.44 38.62 526.82 1704.62
377
Number[1][1][0] Number[1][1][1] Number[1][1][2] Number[1][1][3] Number[1][1][4]
= = = = =
56.85 105.48 363.31 172.62 128.48
Number[1][2][0] Number[1][2][1] Number[1][2][2] Number[1][2][3] Number[1][2][4]
= = = = =
906.68 47.12 -166.07 4444.26 408.62
Number of items 30 Number of items 3
Jagged Arrays Introduction A jagged array is just an array of arrays, or an array of arrays of arrays, etc. To create a jagged array, use a combination of square brackets for each dimension. The formula used is: DataType[][] VariableName; Each of the square brackets is used in any of the ways we have introduced arrays so far. This means that the first square bracket can be used as its own one-dimensional array or as a multi-dimensional array. Here is an example: long[2][5] Distances; This declares a variable that represents two arrays and each array internally contains 5 arrays. The first square bracket can also be used as its own multidimensional array. Here is an example: long[2,4][5] Distances; In the same way, the second square bracket can be used as a single or a multidimensional array. Here is an example: long[2,4][5,12,8] Distances;
Practical Learning: Introducing Jagged Arrays 1. Start a new file in Notepad and type the following: using System; class DepartmentStore { static int Main() { long ItemID = 0; string Description = "Unknown"; decimal Price = 0.00M; Console.WriteLine("Receipt"); Console.WriteLine("Item Number: {0}", ItemID);
378 Console.WriteLine("Description: Console.WriteLine("Unit Price:
{0}", Description); {0:C}\n", Price);
return 0;
} }
2. Save the file in a new folder named DeptStore5 3. Save the file as Exercise.cs 4. Open the Command Prompt and change to the above DeptStore5
5. Compile the exercise with csc Exercise.cs and execute it with Exercise This would produce:
Receipt Item Number: 0 Description: Unknown Unit Price: $0.00 6. Return to Notepad
Initialization of a Jagged Array When declaring a jagged array, you can allocate memory for it using the new operator followed by the data type of the array and the same combination of square brackets used to the left of the assignment operator. The first square of the square brackets on the right side of the assignment operator must contain the external dimension of the array. The second pair of square brackets must be left empty. Here is an example: using System; namespace CSharpLessons { class Exercise { static void Main() { string[][] Members = new string[2][]; } }
} To initialize a jagged array, when declaring the variable, on the right side of the second pair of square brackets, provide an opening and a closing curly brackets, then create each list in its own pair of curly brackets. At the beginning of each list, you must allocate memory for the list with the new operator. Here is an example:
using System; namespace CSharpLessons { class Exercise { static void Main()
379 { "Germain"},
string[][] Members = new string[2][]{ new string[]{"Celeste", "Mathurin", "Alex", new string[]{"Jeremy", "Mathew", "Anselme",
"Frederique"}
}; } }
Console.WriteLine();
} If you initialize the array this way, you can omit specifying the dimension of the external array. With a jagged array, you can also initialize its internal array individually. To do this, access each internal array by its zero-based index. Here is an example:
namespace CSharpLessons { class Exercise { static void Main() { string[][] Members = new string[2][]; Members[0] = new string[]{"Celeste", "Mathurin", "Alex", "Germain"};
Members[1] = new string[]{"Jeremy", "Mathew", "Anselme",
"Frederique"}; } }
Console.WriteLine();
}
Practical Learning: Initializing a Jagged Array 1. To declare and initialize jagged arrays, change the file as follows: using System; class DepartmentStore { static int Main() { // Each of the following variable arrays is structured as [2][2][4]. // Each variable represents: // A/ Two major lists: The first major list represents women items, // the second major list represents men items, // B/ Two minor lists. // Each of the major lists contains two minor lists: // a/ The first minor list of the first major list contains adult women items // The second minor list of the first major list contains girls items // b/ The first minor list of the second major list contains adult men
380 items items
//
The second minor list of the second major list contains boys
// C/ Each minor list contains four items long[][][] ItemNumber = new long[][][]{ new long[][]{ new long[]{947783, 934687, 973947, 987598, 974937}, new long[]{743765, 747635, 765473, 754026, 730302}}, new long[][]{ new long[]{209579, 267583, 248937, 276057, 267945}, new long[]{ 409579, 467583, 448937, 476057, 467945}} }; string[][][] ItemName = new string[][][]{ new string[][]{ new string[]{ "Double-faced wool coat", "Floral Silk Tank Blouse", "Push Up Bra", "Chiffon Blouse", "Bow Belt Skirtsuit" }, new string[]{ "Cable-knit Sweater", "Jeans with Heart Belt", "Fashionable mini skirt", "Double Dry Pants", "Romantic Flower Dress" } }, new string[][]{ new string[]{ "Cotton Polo Shirt", "Pure Wool Cap", "Striped Cotton Shirt", "Two-Toned Ribbed Crewneck", "Chestnut Italian Shoes" }, new string[]{ "Under Collar and Placket Jacket", "Country Coat Rugged Wear", "Carpenter Jeans", "Double-Cushion Tennis Shoes", "Stitched Center-Bar Belt" }} }; decimal[][][] UnitPrice = new decimal[2][][]{ new decimal[][]{ new decimal[]{ 275.25M, 180.00M, 50.00M, 265.00M, 245.55M }, 24.95M }}, 165.75M }, 32.50M }} };
new decimal[]{ 45.55M, 25.65M, 34.55M, 28.55M, new decimal[][]{ new decimal[]{ 45.75M, 25.00M, 65.55M, 9.75M, new decimal[]{ 265.15M, 35.55M, 24.95M, 48.75M, long ItemID = 0; string Description = "Unknown"; decimal Price = 0.00M; Console.WriteLine("Receipt"); Console.WriteLine("Item Number: {0}", ItemID);
381 Console.WriteLine("Description: {0}", Description); Console.WriteLine("Unit Price: {0:C}\n", Price); }
return 0;
} 2. Save the file
Access to Members of a Jagged Array As done for a multidimensional array, each member of a jagged array can be access with a multiple index, depending on how the array was created. Both the external and the internal lists are zerobased. Here is an example: using System; namespace CSharpLessons { class Exercise { static void Main() { string[][] Members = new string[2][]; Members[0] = new string[]{"Celeste", "Mathurin", "Alex", "Germain"}; Members[1] = new string[]{"Jeremy", "Mathew", "Anselme", "Frederique"};
} }
Console.WriteLine("Member Console.WriteLine("Member Console.WriteLine("Member Console.WriteLine("Member Console.WriteLine("Member Console.WriteLine("Member Console.WriteLine("Member Console.WriteLine("Member
1: 2: 3: 4: 5: 6: 7: 8:
{0}", Members[0][0]); {0}", Members[0][1]); {0}", Members[0][2]); {0}", Members[0][3]); {0}", Members[1][0]); {0}", Members[1][1]); {0}", Members[1][2]); {0}\n", Members[1][3]);
} This would produce:
Member Member Member Member Member Member Member Member
1: 2: 3: 4: 5: 6: 7: 8:
Celeste Mathurin Alex Germain Jeremy Mathew Anselme Frederique
Press any key to continue . . .
Practical Learning: Using a Jagged Array 1. To process the members of a jagged array, make the following changes to the file:
382 using System; class DepartmentStore { static int Main() { // Each of the following variable arrays is structured as [2][2][4]. // Each variable represents: // A/ Two major lists: The first major list represents women items, // the second major list represents men items, // B/ Two minor lists. // Each of the major lists contains two minor lists: // a/ The first minor list of the first major list contains adult women items // The second minor list of the first major list contains girls items // b/ The first minor list of the second major list contains adult men items // The second minor list of the second major list contains boys items // C/ Each minor list contains four items long[][][] ItemNumber = new long[][][]{ new long[][]{ new long[]{947783, 934687, 973947, 987598, 974937}, new long[]{743765, 747635, 765473, 754026, 730302}}, new long[][]{ new long[]{209579, 267583, 248937, 276057, 267945}, new long[]{ 409579, 467583, 448937, 476057, 467945}} }; string[][][] ItemName = new string[][][]{ new string[][]{ new string[]{ "Double-faced wool coat", "Floral Silk Tank Blouse", "Push Up Bra", "Chiffon Blouse", "Bow Belt Skirtsuit" }, new string[]{ "Cable-knit Sweater", "Jeans with Heart Belt", "Fashionable mini skirt", "Double Dry Pants", "Romantic Flower Dress" } }, new string[][]{ new string[]{ "Cotton Polo Shirt", "Pure Wool Cap", "Striped Cotton Shirt", "Two-Toned Ribbed Crewneck", "Chestnut Italian Shoes" }, new string[]{ "Under Collar and Placket Jacket", "Country Coat Rugged Wear", "Carpenter Jeans", "Double-Cushion Tennis Shoes", "Stitched Center-Bar Belt" }} }; decimal[][][] UnitPrice = new decimal[2][][]{ new decimal[][]{ new decimal[]{ 275.25M, 180.00M, 50.00M, 265.00M,
383 245.55M }, new decimal[]{ 45.55M, 25.65M, 34.55M, 28.55M,
24.95M }},
new decimal[][]{ new decimal[]{ 45.75M, 25.00M, 65.55M, 9.75M, 165.75M },
new decimal[]{ 265.15M, 35.55M, 24.95M, 48.75M,
32.50M }} }; long ItemID = 0; string Description = "Unknown"; decimal Price = 0.00M; string Category = "Category"; // Order Processing try { Console.Write("Enter Item Number: "); ItemID = long.Parse(Console.ReadLine()); } catch(FormatException) { Console.WriteLine("Invalid Number - The program will terminate\n"); } for(int i = 0; i < 2; i++) { for(int j = 0; j < 2; j++) { for(int k = 0; k < 5; k++) { if( ItemID == ItemNumber[i][j][k] ) { Description = ItemName[i][j][k]; Price = UnitPrice[i][j][k]; if( ItemID >= 900000 ) Category = "Women"; else if( ItemID >= 700000 ) Category = "Girls"; else if( ItemID >= 400000 ) Category = "Boys"; else Category = "Men"; } }
}
}
Console.WriteLine("Receipt"); Console.WriteLine("Item Number: {0}", ItemID); Console.WriteLine("Description: {0} - {1}", Category, Description); Console.WriteLine("Unit Price: {0:C}\n", Price); return 0;
384 } } 2. Save, compile, and execute the file
The .NET Framework Support of Arrays Introduction The techniques we have used to create arrays so far are part of the traditional routines used in many languages. The Microsoft .NET Framework goes further than that. Every time you declare an array, it inherits from a class called Array. The Array class provides support for any array using various properties and methods. After creating an array as we have done so far, you may want to rearrange the list based on one of the items. You may want to look for a particular item to find if it exists; then, if it exists, where it is located. The Array class provides many other routines to perform such operations.
Item Addition As done so far, to add an item to a list, you specify its index and assign the desired value. Here is an example: class Exercise { static void Main() { string[] EmployeeName = new string[4]; EmployeeName[0] EmployeeName[1] EmployeeName[2] EmployeeName[3] }
= = = =
"Joan Fuller"; "Barbara Boxen"; "Paul Kumar"; "Bertrand Entire";
} Alternatively, you can use the SetValue() method to add a new item to the list. This method has 8 versions. The first argument is the value that needs to be added to the list, the other argument(s) is(are) used for the index. Here is an example:
class Exercise { static void Main() { string[] EmployeeName = new string[4];
}
EmployeeName.SetValue("Joan Fuller", 0); EmployeeName.SetValue("Barbara Boxen", 1); EmployeeName.SetValue("Paul Kumar", 2); EmployeeName.SetValue("Bertrand Entire", 3);
}
Item Retrieval To locate an item of an array, we were using its index. Here is an example:
385 class Exercise { static void Main() { string[] EmployeeName = new string[4]; EmployeeName[0] EmployeeName[1] EmployeeName[2] EmployeeName[3]
= = = =
"Joan Fuller"; "Barbara Boxen"; "Paul Kouma"; "Bertand Entire";
Console.WriteLine("Employees Records"); Console.WriteLine("Employee 1: {0}", EmployeeName[0]); Console.WriteLine("Employee 2: {0}", EmployeeName[1]); Console.WriteLine("Employee 3: {0}", EmployeeName[2]); Console.WriteLine("Employee 4: {0}", EmployeeName[3]); }
} Alternatively, the Array class provides the GetValue() method, also loaded with 8 versions. Here is an example:
class Exercise { static void Main() { string[] EmployeeName = new string[4]; EmployeeName.SetValue("Joan Fuller", 0); EmployeeName.SetValue("Barbara Boxen", 1); EmployeeName.SetValue("Paul Kumar", 2); EmployeeName.SetValue("Bertrand Entire", 3); Console.WriteLine("Employees Records"); Console.WriteLine("Employee 1: {0}", EmployeeName.GetValue(0)); Console.WriteLine("Employee 2: {0}", EmployeeName.GetValue(1)); Console.WriteLine("Employee 3: {0}", EmployeeName.GetValue(2)); Console.WriteLine("Employee 4: {0}", EmployeeName.GetValue(3)); }
}
The Length of an Array Once an array has been created, you can use it as you see fit. We saw that, when creating an array, you can specify the number of its members, and you must do this if you are not initializing the array. As we saw already, if you are initializing an array when creating it, you don't have to specify its dimension. Here is an example: using System; namespace CSharpLessons { class Exercise {
386
693};
static void Main() { double[] number = new double[]{ 12.44, 525.38, 6.28, 2448.32, 632.04, -378, 48, 6348, 762, 83, 64, -7, 86, 534, -6, 386, 73, 5, -284, 3654, 671, 34, Console.WriteLine();
}
} Some time in your program, you may want to know how many members are in this type of array. You could get dizzy trying to count them and you may make a mistake with the count. All of the arrays used in C# derive from a class called Array. This class provides a property called Length. To find out how many members an array has, you can access its Length property. Here is an example:
using System; namespace CSharpLessons { class Exercise { static void Main() { double[] number = new double[]{ 12.44, 525.38, 6.28, 2448.32, 632.04, -378, 48, 6348, 762, 83, 64, -7, 86, 534, -6, 386, 73, 5, -284, 3654, 671, 34, 693}; Console.WriteLine("Number of items {0}", number.Length); Console.WriteLine(); }
} This would produce:
Number of items 23
The Dimensions of an Array We have seen that the square brackets are used to specify to the compiler that you are declaring an array. If you are creating a one-dimensional array, we saw that you can type a number in the square bracket. If you are creating a two-dimensional array, you type two numbers separated by a comma in the second pair of square brackets. Each number, whether it is one, two, or more is a place holder for what is referred to a dimension. In other words, a one dimensional array has a dimension of one. A two-dimensional array has a dimension of 2. To find out the dimension of an array, the Array class, which is the parent of all arrays, provides the Rank property. Therefore, to know the dimension of an existing array, you can access its Rank.
The Bounds of an Array To better manage an array, the compiler must always be able to locate its highest and its lowest members. This is particularly important because an array must have a fixed size (by the way, using
387 some gymnastic, an array can grow or shrink, a feature that is not available in C/C++ but can be managed in C# using the .NET Framework). The lowest member of an array can be located using the Array.GetLowerBound() method. Its syntax is: public int GetLowerBound(int dimension); The highest member of an array can be located using the Array.GetUpperBound() method. Its syntax is: public int GetUpperBound(int dimension); In both cases, the dimension argument is the rank of the array. For a single-dimensional array, as those we have always used so far, this parameter must have the value of 0;
Previous
Copyright © 2004-2006 FunctionX, Inc.
Arrays and Classes Primitive Arrays as Fields Introduction As we have used so far, an array is primarily a variable. As such, it can be declared as a field. To create a field as an array, you can declare it like a normal array in the body of the class. Here is an example: using System; namespace Arithmetic { class NumberCrunching { double[] number; } }
Next
388
Practical Learning: Introducing Primitive Arrays as Fields of a Class 1. Start Notepad and, in the empty file, type the following: using System; namespace VendingMachine { // This class is used to create an ice cream // And to process an order sealed class IceCream { } }
2. Save the file in a new folder named IceCream3 3. Save the file itself as IceCream.cs in the IceCream3 folder 4. Start a new instance of Notepad and type the following: using System; // This is the main class used to manage the application class Exercise { static int Main() { return 0; } }
5. Save the file as Exercise.cs in a the above IceCream3 folder 6. To declare fields as arrays, access the IceCream.cs file and change it as follows: using System; namespace VendingMachine { // This class is used to create an ice cream // And to process an order sealed class IceCream { // These arrays are used to build the components of various ice creams private string[] Flavor; private string[] Container; private string[] Ingredient; } } 7. Save the file
A Primitive Array as a Field
389
Like any field, when an array has been declared as a member variable, it is made available to all the other members of the same class. You can use this feature to initialize the array in one method and let other methods use the initialized variable. This also means that you don't have to pass the array as argument nor do you have to explicitly return it from a method. After or when declaring an array, you must make sure you allocate memory for it prior to using. Unlike C++, you can allocate memory for an array when declaring it. Here is an example: using System; namespace Arithmetic { class NumberCrunching { double[] number = new double[5]; } } You can also allocate memory for an array field in a constructor of the class. Here is an example: using System; namespace Arithmetic { class NumberCrunching { double[] Number; public NumberCrunching() { Number = new double[5]; } }
} If you plan to use the array as soon as the program is running, you can initialize it using a constructor or a method that you know would be before the array can be used. Here is an example:
using System; namespace Arithmetic { class NumberCrunching { double[] Number = new double[5];
}
public NumberCrunching() { Number[0] = 12.44; Number[1] = 525.38; Number[2] = 6.28; Number[3] = 2448.32; Number[4] = 632.04; }
390 }
Practical Learning: Creating Fields as Primitive Arrays in a Class 1. To initialize the arrays of the class, change the IceCream.cs file as follows: using System; namespace VendingMachine { // This class is used to create an ice cream // And to process an order sealed class IceCream { // These arrays are used to build the components of various ice creams // In C#, we can allocate an array's memory in the body of the class private string[] Flavor = new string[10]; private string[] Container; private string[] Ingredient; // This default constructor is the best place for us to initialize the array public IceCream() { Flavor[0] = "Vanilla"; Flavor[1] = "Cream of Cocoa"; Flavor[2] = "Chocolate Chip"; Flavor[3] = "Organic Strawberry"; Flavor[4] = "Butter Pecan"; Flavor[5] = "Cherry Coke"; Flavor[6] = "Chocolate Brownies"; Flavor[7] = "Caramel Au Lait"; Flavor[8] = "Chunky Butter"; Flavor[9] = "Chocolate Cookie"; Ingredient = Ingredient[0] Ingredient[1] Ingredient[2] Ingredient[3]
new string[4]; = "No Ingredient"; = "Peanuts"; = "M & M"; = "Cookies";
Container = new string[3]; Container[0] = "Cone"; Container[1] = "Cup"; Container[2] = "Bowl"; }
}
} 2. Save the file
Use of a Primitive Array as a Field
391 Remember that, after an array is made a field, it can be used by any other member of the same class. Based on this, you can use a member of the same class to request values that would initialize it. You can also use another method to explore the array. Here is an example: using System; namespace Arithmetic { class NumberCrunching { double[] Number = new double[5]; public NumberCrunching() { Number[0] = 12.44; Number[1] = 525.38; Number[2] = 6.28; Number[3] = 2448.32; Number[4] = 632.04; }
}
public void DisplayNumber() { for (int i = 0; i < 5; i++) Console.WriteLine("Number {0}: {1}", i, Number[i]); }
class Program { static void Main() { NumberCrunching lstNumber = new NumberCrunching(); lstNumber.DisplayNumber(); }
}
}
Practical Learning: Using Primitive Arrays in a Class 1. To use the arrays throughout the class, change the IceCream.cs file as follows: using System; namespace VendingMachine { // This class is used to create and manage an ice cream // and to process an order sealed class IceCream { // This is the base price of an ice cream // Optional values may be added to it public const decimal BasePrice = 1.55M; // These arrays are used to build the components of various ice creams // In C#, we can allocate an array's memory in the body of the class
392 private string[] Flavor = new string[10]; private string[] Container; private string[] Ingredient; // Additional factor used to process an ice cream order private int Scoops; private decimal TotalPrice; // This default constructor is the best place for us to initialize the array public IceCream() { Flavor[0] = "Vanilla"; Flavor[1] = "Cream of Cocoa"; Flavor[2] = "Chocolate Chip"; Flavor[3] = "Organic Strawberry"; Flavor[4] = "Butter Pecan"; Flavor[5] = "Cherry Coke"; Flavor[6] = "Chocolate Brownies"; Flavor[7] = "Caramel Au Lait"; Flavor[8] = "Chunky Butter"; Flavor[9] = "Chocolate Cookie"; Ingredient = Ingredient[0] Ingredient[1] Ingredient[2] Ingredient[3]
}
new string[4]; = "No Ingredient"; = "Peanuts"; = "M & M"; = "Cookies";
Container = new string[3]; Container[0] = "Cone"; Container[1] = "Cup"; Container[2] = "Bowl";
// This method requests a flavor from the user and returns the choice public int ChooseFlavor() { int Choice = 0; // Make sure the user selects a valid number that represents a flavor... do { // In case the user types a symbol that is not a number try { Console.WriteLine("What type of flavor do you want?"); for(int i = 0; i < Flavor.Length; i++) Console.WriteLine("{0} - {1}", i+1, Flavor[i]); Console.Write("Your Choice? " ); Choice = int.Parse(Console.ReadLine()); } catch(FormatException) // display an appropriate message { Console.WriteLine("You must enter a valid number and no other character!"); }
393 // If the user typed an invalid number out of the allowed range // let him or her know and provide another chance if( Choice < 1 || Choice > Flavor.Length ) Console.WriteLine("Invalid Choice - Try Again!\n"); } while( Choice < 1 || Choice > Flavor.Length );
}
// Return the numeric choice that the user made return Choice;
// This method allows the user to select a container public int ChooseContainer() { int Choice = 0; // Make sure the user selects a valid number that represents a container do { // If the user types a symbol that is not a number try { Console.WriteLine("What type of container do you want?"); for(int i = 0; i < Container.Length; i++) Console.WriteLine("{0} - {1}", i+1, Container[i]); Console.Write("Your Choice? "); Choice = int.Parse(Console.ReadLine()); } catch(FormatException) // display an appropriate message { Console.WriteLine("You must enter a valid number and no other character!"); } // If the user typed an invalid number out of the allowed range // let him or her know and provide another chance if( Choice < 1 || Choice > Container.Length ) Console.WriteLine("Invalid Choice - Try Again!"); } while( Choice < 1 || Choice > Container.Length );
}
// Return the numeric choice that the user made return Choice;
public int ChooseIngredient() { int Choice = 0; do {
try {
}
Console.WriteLine("Do you want an ingredient or not"); for(int i = 0; i < Ingredient.Length; i++) Console.WriteLine("{0} - {1}", i+1, Ingredient[i]); Console.Write("Your Choice? "); Choice = int.Parse(Console.ReadLine());
394 catch(FormatException) { Console.WriteLine("You must enter a valid number and no other character!"); } if( Choice < 1 || Choice > Ingredient.Length ) Console.WriteLine("Invalid Choice - Try Again!"); } while( Choice < 1 || Choice > Ingredient.Length ); }
return Choice;
public void SpecifyNumberOfScoops() { do { try { Console.Write("How many scoops(1, 2, or 3)? "); Scoops = int.Parse(Console.ReadLine()); } catch(FormatException) { Console.WriteLine("You must enter a valid number and no other character!"); } if( Scoops < 1 || Scoops > 3 ) Console.WriteLine("Invalid Choice - Try Again!"); } while( Scoops < 1 || Scoops > 3 ); } // This method is used to process a customer order // It uses the values of the above methods public void ProcessAnOrder() { int ChoiceFlavor; int ChoiceContainer; int ChoiceIngredient; decimal PriceIngredient, PriceScoop; // Let the user know that this is a vending machine Console.WriteLine("Ice Cream Vending Machine"); // Let the user select the components of the ice cream ChoiceFlavor = ChooseFlavor(); ChoiceContainer = ChooseContainer(); ChoiceIngredient = ChooseIngredient(); SpecifyNumberOfScoops(); // If the user selects an ingredient instead of "No Ingredient", // add $0.50 to the order if( ChoiceIngredient == 2 || ChoiceIngredient == 3 || ChoiceIngredient == 4 ) PriceIngredient = 0.50M; else PriceIngredient = 0.00M;
395 // Instead of multiplying a number scoops to a value, // We will use an incremental value depending on the number of scoops if( Scoops == 1 ) PriceScoop = 0.65M; else if( Scoops == 2 ) PriceScoop = 1.05M; else PriceScoop = 1.55M; // Calculate the total price of the ice cream TotalPrice = BasePrice + PriceScoop + PriceIngredient; // Create the ice cream...
}
}
// And display a receipt to the user DisplayReceipt(ref ChoiceFlavor, ref ChoiceContainer, ref ChoiceIngredient);
// This method is used to display a receipt to the user public void DisplayReceipt(ref int Flv, ref int Cnt, ref int Igr) { Console.WriteLine("\nIce Cream Order"); Console.WriteLine("Flavor: {0}", Flavor[Flv-1]); Console.WriteLine("Container: {0}", Container[Cnt-1]); Console.WriteLine("Ingredient: {0}", Ingredient[Igr-1]); Console.WriteLine("Scoops: {0}", Scoops); Console.WriteLine("Total Price: {0:C}\n", TotalPrice); }
} 2. Save the IceCream.cs file 3. Access the Exercise.cs file and change it as follows: using System; namespace VendingMachine { // This is the main class used to manage the application class Exercise { static int Main() { VendingMachine.IceCream IS = new VendingMachine.IceCream(); IS.ProcessAnOrder(); return 0; }
}
} 4. Save the Exercise.cs file 5. Open the Command Prompt and change to the directory that contains the above Exercise.cs file
396 6. To compile it, type csc /out:"Ice Cream Vending Machine".exe IceCream.cs Exercise.cs and press Enter
7. To execute it, type "Ice Cream Vending Machine" and press Enter. Here is an example: C:\>CD CSharp Lessons\IceCream3 C:\CSharp Lessons\IceCream3>csc /out:"Ice Cream Vending Machine".exe IceCream .cs Exercise.cs Microsoft (R) Visual C# .NET Compiler version 7.10.3052.4 for Microsoft (R) .NET Framework version 1.1.4322 Copyright (C) Microsoft Corporation 2001-2002. All rights reserved. C:\CSharp Lessons\IceCream3>"Ice Cream Vending Machine" Ice Cream Vending Machine What type of flavor do you want? 1 - Vanilla 2 - Cream of Cocoa 3 - Chocolate Chip 4 - Organic Strawberry 5 - Butter Pecan 6 - Cherry Coke 7 - Chocolate Brownies 8 - Caramel Au Lait 9 - Chunky Butter 10 - Chocolate Cookie Your Choice? 8 What type of container do you want? 1 - Cone 2 - Cup 3 - Bowl Your Choice? 2 Do you want an ingredient or not 1 - No Ingredient 2 - Peanuts 3 - M & M 4 - Cookies Your Choice? 6 Invalid Choice - Try Again! Do you want an ingredient or not 1 - No Ingredient 2 - Peanuts 3 - M & M 4 - Cookies Your Choice? g You must enter a valid number and no other character! Invalid Choice - Try Again! Do you want an ingredient or not 1 - No Ingredient 2 - Peanuts 3 - M & M 4 - Cookies Your Choice? 2 How many scoops(1, 2, or 3)? 2
397 Ice Cream Order Flavor: Caramel Au Lait Container: Cup Ingredient: Peanuts Scoops: 2 Total Price: $3.10 C:\CSharp Lessons\IceCream3> 8. Return to Notepad
foreach Item in the Series In the previous lessons, we used the traditional techniques of locating each item in an array. Here is an example: class Exercise { static int Main() { string[] EmployeeName = new string[4]; EmployeeName[0] EmployeeName[1] EmployeeName[2] EmployeeName[3]
= = = =
"Joan Fuller"; "Barbara Boxen"; "Paul Kumar"; "Bertrand Entire";
Console.WriteLine("Employees Records"); Console.WriteLine("Employee 1: {0}", EmployeeName[0]); Console.WriteLine("Employee 2: {0}", EmployeeName[1]); Console.WriteLine("Employee 3: {0}", EmployeeName[2]); Console.WriteLine("Employee 4: {0}", EmployeeName[3]); return 0; }
} To scan a list, the C# language provides two keyword, foreach and in, with the following syntax:
foreach (type identifier in expression) statement
398
ms+=