P. 1
C# 3.0 Practical Learning I

C# 3.0 Practical Learning I

|Views: 638|Likes:
Published by api-19969170

More info:

Published by: api-19969170 on Dec 03, 2009
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as DOC, PDF, TXT or read online from Scribd
See more
See less

01/25/2015

pdf

text

original

Sections

Visual C# 3.

0 Application Design

FunctionX Press

C# 3.0 Practical Learning

2

INDEX
1 - INTRODUCTION TO C#.................................................................................15 INTRODUCTION.....................................................................................................15 C# is a Sharp C...........................................................................................15 Console Applications..................................................................................15 WRITING CODE....................................................................................................17 Practical Learning: Creating a Program......................................................17 Comments..................................................................................................17 Practical Learning: Creating Comments......................................................17 Code Colors................................................................................................18 Indentation ...............................................................................................19 SOLUTION AND PROJECT MANAGEMENT..........................................................................19 A Project ...................................................................................................19 Saving a Project ........................................................................................20 A Solution...................................................................................................20 Executing a Project....................................................................................22 Practical Learning: Executing an Application..............................................23 Adding a Project ........................................................................................23 2 - INTRODUCTION TO VARIABLES...................................................................26 VARIABLES..........................................................................................................26 Practical Learning: Introducing Variables..................................................26 Names in C#...............................................................................................26 Values and Variables on the Console..........................................................28 THE NUMERIC SYSTEMS...........................................................................................28 The Binary System.....................................................................................29 The Decimal System...................................................................................29 The Hexadecimal System...........................................................................30 Signed and Unsigned..................................................................................31 Data Types.................................................................................................31 REPRESENTING NUMBERS.........................................................................................33 A Bit...........................................................................................................33 The Four-Bit Combination...........................................................................33 A BYTE.............................................................................................................36 Characters..................................................................................................38 Escape Sequences......................................................................................38 The Byte Data Type....................................................................................39 Practical Learning: Using Bytes..................................................................41 Signed Byte................................................................................................42 A WORD...........................................................................................................42 Short Integers............................................................................................43 Unsigned Short Integers............................................................................44 Practical Learning: Using Unsigned Short Integers....................................45 3 – USING VARIABLES......................................................................................47 A DOUBLE-WORD.................................................................................................47 Practical Learning: Using Unsigned Integers..............................................49 Signed Integers..........................................................................................50 Unsigned Integers......................................................................................51 Practical Learning: Using Unsigned Integers..............................................52 A QUAD-WORD...................................................................................................53 Long Integers.............................................................................................54 Unsigned Long Integers.............................................................................56 REAL NUMBERS....................................................................................................56 Floating-Point Numbers.............................................................................57 Double-Precision Numbers.........................................................................57 Practical Learning: Using a Double-Precision Variable...............................59 Decimal......................................................................................................60

C# 3.0 Practical Learning

3

Practical Learning: Using Decimal Values...................................................63 ACCESSORY DATA TYPES..........................................................................................64 Strings.......................................................................................................64 Practical Learning: Using Strings...............................................................65 Dates and Times.........................................................................................67 Objects.......................................................................................................67 CONSTANTS.........................................................................................................69 Custom Constants......................................................................................69 Built-in Constants.......................................................................................71 4 - INTRODUCTION TO CLASSES.......................................................................73 FUNDAMENTALS OF CLASSES......................................................................................73 Practical Learning: Introducing Classes.....................................................73 Creating a Class.........................................................................................73 Practical Learning: Introducing Classes.....................................................75 Visually Managing Classes..........................................................................75 Declaring a Variable of a Class Type...........................................................76 Sharing a Class...........................................................................................78 Garbage Collection.....................................................................................78 CLASS' FIELDS.....................................................................................................79 Practical Learning: Introducing Class Members..........................................79 ACCESSING CLASS MEMBERS.....................................................................................81 Private Members........................................................................................81 Internal Members.......................................................................................82 INITIALIZING AN OBJECT..........................................................................................82 Practical Learning: Using a Class' Fields.....................................................84 Using an Anonymous Type.........................................................................85 THE METHODS OF A CLASS.......................................................................................86 The Solution Explorer.................................................................................88 Practical Learning: Creating the Methods of a Class...................................89 Accessing a Method....................................................................................91 THE STATIC MEMBERS OF A CLASS..............................................................................92 Static Fields................................................................................................92 Static Methods...........................................................................................96 Static Classes.............................................................................................97 CHARACTERISTICS OF MEMBERS OF A CLASS....................................................................98 Constants...................................................................................................98 this Instance..............................................................................................98 Practical Learning: Using this.....................................................................99 5 - C# AND CODE ORGANIZATION...................................................................101 NAMESPACES......................................................................................................101 Practical Learning: Creating a Namespacep> ..........................................101 Accessing Members of a Namespace........................................................102 Namespace Nesting..................................................................................103 THE SYSTEM NAMESPACE.......................................................................................104 Using a Namespace..................................................................................105 Practical Learning: Using the Keyword.....................................................105 .NET SUPPORT OF DATA TYPES...............................................................................105 C# LANGUAGE ACCESSORIES...................................................................................106 Command Line Options.............................................................................106 Unsafe Code.............................................................................................107 Code Editor Region Delimiter...................................................................109 6 - DATA READING AND FORMATTING............................................................114 DATA READING..................................................................................................114 Practical Learning: Introducing Data Reading..........................................114 String Value Request ...............................................................................114 Practical Learning: Reading String Values................................................115

C# 3.0 Practical Learning

4

Number Request.......................................................................................116 Practical Learning: Reading Numeric Values............................................117 Requesting Dates and Times....................................................................119 Practical Learning: Requesting Date and Time Values..............................120 FORMATTING DATA DISPLAY....................................................................................123 Practical Learning: Displaying Data With Placeholders.............................124 Conversion To String................................................................................126 Practical Learning: Converting to String...................................................127 Number Formatting..................................................................................127 Practical Learning: Formatting Data Display............................................129 Line Formatting........................................................................................132 Data and Time Formatting........................................................................132 Practical Learning: Controlling Date/Time Formatting.............................133 DETAILS ON THE METHODS OF A CLASS..........................................................136 METHODS AND LOCAL VARIABLES..............................................................................136 Practical Learning: Using a Method's Local Variables...............................136 A Method that Returns a Value ................................................................138 Practical Learning: Returning a Value From a Method .............................139 The Main Method of an Application...........................................................140 METHODS' ARGUMENTS..........................................................................................141 Practical Learning: Passing Arguments....................................................142 TECHNIQUES OF PASSING ARGUMENTS.........................................................................144 Passing an Argument by Value.................................................................144 Passing an Argument by Reference..........................................................144 Practical Learning: Passing Arguments By Reference...............................147 Method Overloading.................................................................................148 Practical Learning: Overloading a Method................................................149 CLASS CONSTRUCTION AND DESTRUCTION.....................................................................153 Method Initializer.....................................................................................153 Default Constructor..................................................................................156 The Constructor Initializer.......................................................................157 Constructor Overloading..........................................................................158 The Destructor of a Class.........................................................................160 COMBINATIONS OF CLASSES..........................................................................162 CLASSES COMBINATIONS........................................................................................162 Class Nesting............................................................................................162 A Class as a Field......................................................................................166 Practical Learning: Using a Class as a Field..............................................167 RETURNING A CLASS OR PASSING A CLASS...................................................................169 Returning a Class From a Method.............................................................169 Passing a Class as Argument....................................................................170 Practical Learning: Return a Class or Passing One as Argument...............173 INVOLVING A CLASS AND ITS OWN METHODS................................................................176 Passing a Class as its Own Argument.......................................................176 Returning a Class From its Own Method...................................................180 INTRODUCTION TO CONDITIONS....................................................................184 BOOLEAN VARIABLES............................................................................................184 Practical Learning: Introducing Boolean Variables...................................184 Declaring a Boolean Variable....................................................................188 Retrieving the Value of a Boolean Variable...............................................190 Creating a Boolean Field...........................................................................190 Boolean Arguments..................................................................................192 ENUMERATIONS...................................................................................................192 Declaring an Enumeration Variable..........................................................194 Initializing an Enumeration Variable........................................................194 Enumerations Visibility............................................................................196

C# 3.0 Practical Learning

5

An Enumeration as a Member Variable.....................................................196 Practical Learning: Creating and Using Enumerations..............................198 LOGICAL OPERATORS............................................................................................202 The Equality Operator ==.........................................................................203 The Logical Not Operator !........................................................................204 The Inequality Operator !=......................................................................205 The Comparison for a Lower Value <........................................................206 Combining Equality and Lower Value <=..................................................207 The Comparison for a Greater Value >.....................................................208 The Greater Than or Equal Operator >=...................................................208 LOGICALLY INCREMENTING OR DECREMENTING A VALUE.....................................................209 Incrementing a Variable...........................................................................209 Pre and Post-Increment...........................................................................211 Decrementing a Value..............................................................................212 Pre Decrementing a Value........................................................................214 Techniques of Incrementing and Decrementing a Variable......................215 CONDITIONAL STATEMENTS...........................................................................218 CONDITION IS TRUE.......................................................................................218 Practical Learning: Introducing Conditional Expressions..........................218 if..............................................................................................................219 Practical Learning: Using the Simple if Condition.....................................224 if…else.....................................................................................................226 Practical Learning: Using the if...else Condition.......................................228 LOGICAL CONJUNCTION: AND.................................................................................231 Combining Conjunctions...........................................................................238 LOGICAL DISJUNCTION: OR....................................................................................241 Combinations of Disjunctions...................................................................245
IF A

CONDITIONAL SWITCHES...............................................................................246 SWITCHES.....................................................................................................246 The Ternary Operator (?:)........................................................................246 Practical Learning: Introducing Conditional Switches..............................247 if…else if and if…else if…else...................................................................248 CASE SWITCHES..................................................................................................251 Practical Learning: Using Conditional Switches........................................256 Combining Cases......................................................................................260 Using Enumerations.................................................................................262
IF

COUNTING AND LOOPING...............................................................................264 CONDITIONAL LOOPING.........................................................................................264 while a Condition is True..........................................................................264 do This while a Condition is True..............................................................265 Practical Learning: Introducing Counting and Looping.............................267 for............................................................................................................273 CONTROLLING THE CONDITIONAL STATEMENTS................................................................274 Nesting a Conditional Statement..............................................................274 Practical Learning: Nesting Conditions.....................................................276 Breaking the Flow of a Conditional Statement..........................................281 Continuing a Conditional Statement.........................................................282 Going to a Designated Label.....................................................................283 Conditional Return...................................................................................283 RECURSION.......................................................................................................285 Creating a Recursive Methods..................................................................286 Using Recursive Methods.........................................................................287 THE PROPERTIES OF A CLASS.........................................................................289 OVERVIEW OF PROPERTIES......................................................................................289 Accessories for Properties........................................................................289 Practical Learning: Introducing Properties...............................................290

C# 3.0 Practical Learning

6

TYPES OF PROPERTIES...........................................................................................291 Property Readers.....................................................................................291 Practical Learning: Creating Property Readers.........................................294 Property Writers......................................................................................297 Read/Write Properties.............................................................................299 Practical Learning: Creating Property Writers..........................................299 A Boolean Property..................................................................................302 PROPERTIES OF EXTERNAL CLASSES............................................................................303 Properties and Enumerations...................................................................303 Practical Learning: Creating an Enumeration Property.............................303 A Class as a Property................................................................................306 Practical Learning: Creating a Property of a Class Type...........................307 INHERITANCE.................................................................................................313 INTRODUCTION TO INHERITANCE...............................................................................313 Practical Learning: Introducing Inheritance.............................................313 Class Derivation.......................................................................................319 Practical Learning: Inheriting...................................................................324 Implementation of Derived Members ......................................................330 The new Modifier......................................................................................334 POLYMORPHISM AND ABSTRACTION..............................................................336 CHARACTERISTICS OF INHERITANCE............................................................................336 Namespaces and Inheritance...................................................................336 Practical Learning: Using Inheritance With Namespaces..........................338 Protected Members..................................................................................339 Virtual Members.......................................................................................341 Practical Learning: Using Virtual Members...............................................342 Abstract Classes.......................................................................................345 Practical Learning: Creating an Abstract Class.........................................345 Abstract Properties and Methods.............................................................346 Practical Learning: Creating an Abstract Property....................................346 Sealed Classes..........................................................................................349 INTERFACES.......................................................................................................350 Practical Learning: Introducing Interfaces...............................................350 The Members of an Interface...................................................................350 Practical Learning: Creating Members of an Interface..............................351 AN INTERFACE AS A BASE CLASS..............................................................................352 Practical Learning: Inheriting From an Interface.....................................352 Implementation of Derived Classes of an Interface..................................353 Practical Learning: Implementing Derived Members of an Interface........356 Class Partial Implementation...................................................................360 Practical Learning: Partially Implementing a Class..................................365 DELEGATES AND EVENTS.................................................................................371 FUNDAMENTALS OF DELEGATES.................................................................................371 Practical Learning: Introducing Delegates...............................................371 Creating a Delegate..................................................................................376 ACCESSING A DELEGATE.........................................................................................377 A Static Method for a Delegate.................................................................378 An Anonymous Delegate..........................................................................379 The Lambda Operator...............................................................................380 A Delegate that Returns a Value...............................................................381 Delegates Compositions...........................................................................382 DELEGATES AND ARGUMENTS...................................................................................382 Using an Argumentative Delegate............................................................383 A Lambda Expression...............................................................................384 A Delegate With Many Arguments............................................................386 Practical Learning: Passing Arguments to a Delegate..............................387

C# 3.0 Practical Learning

7

A Delegate Passed as Argument...............................................................391 DELEGATES AND CLASSES.......................................................................................394 A Delegate that Returns an Object...........................................................395 A Delegate that Takes an Object as Argument.........................................397 EVENTS............................................................................................................398 Event Creation..........................................................................................399 STRUCTURES...................................................................................................402 FUNDAMENTALS OF STRUCTURES................................................................................402 Structure Declaration...............................................................................403 TECHNIQUES OF USING STRUCTURES...........................................................................404 A Structure as a Property.........................................................................404 Returning a Structure From a Method......................................................406 Passing a Structure as Argument.............................................................407 BUILT-IN STRUCTURES: THE INTEGRAL DATA TYPES.......................................................411 Conversion to a String..............................................................................411 Parsing a String........................................................................................411 The Minimum and Maximum Values of a Primitive Type...........................414 Value Comparisons...................................................................................417 BUILT-IN STRUCTURES: THE BOOLEAN TYPE.................................................................420 Parsing a Boolean Variable.......................................................................420 Comparisons of Boolean Variables...........................................................422 FLOATING-POINT NUMBERS....................................................................................424 Operations on Floating-Point Numbers.....................................................425 Comparison Operations............................................................................426 BUILT-IN CLASSES..........................................................................................428 THE OBJECT CLASS..............................................................................................428 Practical Learning: Introducing Ancestor Classes.....................................428 Equality of Two Class Variables................................................................430 Practical Learning: Implementing Equality...............................................431 Stringing a Class......................................................................................432 Practical Learning: Converting to String...................................................433 Boxing and Un-Boxing..............................................................................435 Finalizing a Variable.................................................................................437 Other Built-In Classes..............................................................................437 RANDOM NUMBERS...............................................................................................437 Getting a Random Number.......................................................................437 The Seed of a Random Number................................................................439 Generating Random Numbers in a Range of Numbers..............................440 BUILT-IN ASSEMBLIES AND LIBRARIES........................................................................442 Microsoft Visual Basic Functions..............................................................442 C# CUSTOM LIBRARIES.........................................................................................443 Creating a Library.....................................................................................443 Practical Learning: Creating a Library......................................................444 A LIBRARY CREATED IN ANOTHER LANGUAGE................................................................447 Using a Visual C++/CLI Library................................................................447 Creating a Library.....................................................................................447 Using the Library......................................................................................448 Using the Win32 Library...........................................................................449 INTRODUCTION TO EXCEPTION HANDLING....................................................450 INTRODUCTION TO EXCEPTIONS.................................................................................450 Overview..................................................................................................450 Practical Learning: Introducing Exception Handling.................................451 Exceptional Behaviors..............................................................................454 Practical Learning: Introducing Vague Exceptions...................................456 Exceptions and Custom Messages............................................................457 Practical Learning: Displaying Custom Messages.....................................458

C# 3.0 Practical Learning

8

EXCEPTIONS IN THE .NET FRAMEWORK.......................................................................460 The Exception Class..................................................................................460 The Exception's Message..........................................................................461 Custom Error Messages............................................................................462 A REVIEW OF .NET EXCEPTION CLASSES....................................................................463 The FormatException Exception...............................................................464 Practical Learning: Using the FormatException Class...............................465 The OverflowException Exception............................................................469 The ArgumentOutOfRangeException Exception........................................469 The DivideByZeroException Exception......................................................470 USING EXCEPTION HANDLING........................................................................472 TECHNIQUES OF USING EXCEPTIONS...........................................................................472 Practical Learning: Using Exceptions........................................................472 Throwing an Exception.............................................................................481 Practical Learning: Throwing an Exception...............................................482 Catching Various Exceptions....................................................................485 Practical Learning: Catching Various Exceptions......................................488 Exception Nesting....................................................................................495 Exceptions and Methods...........................................................................497 CUSTOM EXCEPTIONS............................................................................................502 Creating an Exceptional Class..................................................................502 INTRODUCTION TO ARRAYS............................................................................506 A SERIES OF SIMILAR ITEMS..................................................................................506 Practical Learning: Introducing Arrays.....................................................507 Array Creation..........................................................................................507 Practical Learning: Creating an Array.......................................................508 Introduction to Initializing an Array.........................................................508 Practical Learning: Initializing Some Arrays.............................................510 Other Techniques of Initializing an Array.................................................511 ACCESSING THE MEMBERS OF AN ARRAY......................................................................513 Practical Learning: Using the Members of an Array..................................514 For an Indexed Member of the Array........................................................515 Practical Learning: Using a for Loop.........................................................518 For Each Member in the Array..................................................................520 ANONYMOUS ARRAYS............................................................................................521 Creating an Anonymous Array..................................................................521 Accessing the Members of an Anonymous Array......................................523 SELECTING A VALUE FROM AN ARRAY.........................................................................525 Using for and foreach...............................................................................525 Practical Learning: Checking a Value From an Array................................526 ARRAYS AND CLASSES....................................................................................529 AN ARRAY OF A PRIMITIVE TYPE AS A FIELD................................................................529 Practical Learning: Introducing Arrays and Classes.................................530 Presenting the Array................................................................................531 Practical Learning: Presenting an Array...................................................532 ARRAYS AND METHODS..........................................................................................533 An Array Passed as Argument..................................................................534 Returning an Array From a Method..........................................................536 MAIN()'S ARGUMENT...........................................................................................538 Command Request from Main()................................................................539 AN ARRAY OF OBJECTS.........................................................................................541 Practical Learning: Introducing Arrays of Objects....................................542 Creating an Array of Objects....................................................................543 Initializing an Array of Objects.................................................................544 Accessing the Members of the Array........................................................546 Practical Learning: Using an Array of Objects..........................................548

C# 3.0 Practical Learning

9

A CLASS ARRAY AS A FIELD...................................................................................550 Using the Array........................................................................................551 ARRAYS OF OBJECTS AND METHODS...........................................................................554 Passing an Array of Objects as Argument.................................................554 Returning an Array of Objects..................................................................555 Practical Learning: Using Array of Objects With Methods.........................557 ARRAYS AND DELEGATES........................................................................................559 An Array of Delegates..............................................................................560 MULTIDIMENSIONAL ARRAYS.........................................................................562 FUNDAMENTALS OF MULTIDIMENSIONAL ARRAYS.............................................................562 Practical Learning: Introducing Multidimensional Arrays.........................562 Creating a Two-Dimensional Array...........................................................563 Practical Learning: Creating a Two-Dimensional Array.............................565 Accessing the Members of a Two-Dimensional Array...............................566 Practical Learning: Accessing the Members..............................................569 MULTIDIMENSIONAL ARRAYS....................................................................................571 Creating a Multidimensional Array...........................................................571 Initializing a Multidimensional Array........................................................572 Access to Members of a Multidimensional Array.......................................572 MULTIDIMENSIONAL ARRAYS AND CLASSES...................................................................577 A Multidimensional Array as Argument....................................................579 Returning a Multi-Dimensional Array.......................................................580 A MULTIDIMENSIONAL ARRAY OF OBJECTS...................................................................582 A Variable of a Multidimensional Array of Objects....................................582 Accessing the Members of a Multidimensional Array of Objects...............585 MULTIDIMENSIONAL ARRAYS OF OBJECTS AND CLASSES.....................................................586 Passing a Multidimensional Array of Objects............................................588 Returning a Multidimensional Array of Objects........................................589 INTRODUCTION TO JAGGED ARRAYS............................................................................591 Practical Learning: Introducing Jagged Arrays.........................................591 Initialization of a Jagged Array................................................................592 Practical Learning: Initializing a Jagged Array.........................................593 Access to Members of a Jagged Array......................................................595 Practical Learning: Using a Jagged Array.................................................597 THE ARRAY CLASS...........................................................................................601 INTRODUCTION TO THE ARRAY CLASS..........................................................................601 Overview..................................................................................................601 The Length of an Array.............................................................................602 The Rank of an Array................................................................................603 FUNDAMENTAL OPERATIONS ON AN ARRAY....................................................................603 Adding Items to an Array.........................................................................603 Accessing the Members of an Array..........................................................604 MULTIDIMENSIONAL ARRAYS....................................................................................605 Two-Dimensional Arrays..........................................................................606 Three-Dimensional Arrays........................................................................608 Multidimensional Arrays...........................................................................613 ARRANGING THE LIST...........................................................................................614 Arranging the Items in Alphabetical or Numerical Order..........................614 Reversing the Arrangement.....................................................................615 LOCATING AN ELEMENT IN AN ARRAY..........................................................................615 Locating the Index of an Element.............................................................615 The Bounds of an Array............................................................................616 STRINGS.........................................................................................................618 THE CHARACTERS OF A STRING................................................................................618 Practical Learning: Introducing Strings....................................................619 The String: An Array of Characters ..........................................................628

C# 3.0 Practical Learning

10

Converting Characters to the Opposite Case............................................629 Replacing a Character..............................................................................631 WORKING WITH STRINGS......................................................................................632 The Length of a String..............................................................................632 Practical Learning: Using Characters of a String......................................633 Replacing a Sub-String.............................................................................637 Formatting a String..................................................................................637 Copying a String.......................................................................................638 OPERATIONS ON STRINGS.......................................................................................639 String Concatenation................................................................................639 STRINGS COMPARISONS.........................................................................................641 String Equality..........................................................................................642 WORKING WITH SUB-STRINGS................................................................................643 Sub-String Creation..................................................................................643 INTRODUCTION TO INDEXERS........................................................................644 A PROPERTY CAN BE INDEXED................................................................................644 Practical Learning: Introducing Indexed Properties.................................645 An Indexer...............................................................................................649 Indexed Properties of Other Primitive Types............................................650 Using a Non-Integer-Based Index............................................................652 Practical Learning: Creating an Indexer...................................................655 TOPICS ON INDEXED PROPERTIES..............................................................................657 Multi-Parameterized Indexed Properties..................................................657 Overloading an Indexed Property.............................................................661 READ/WRITE INDEXED PROPERTIES..........................................................................664 A Read/Write Property of a Primitive Type..............................................665 CLASSES AND INDEXERS.................................................................................668 FUNDAMENTALS OF INDEXED PROPERTIES AND CLASSES.....................................................668 Practical Learning: Introducing Indexers and Classes..............................668 An Integer-Based Indexed Property.........................................................672 Practical Learning: Using an Integer-Based Indexer................................675 An Indexed Property Using Another Primitive Type.................................676 TOPICS ON INDEXED PROPERTIES AND CLASSES..............................................................680 A Class as Index.......................................................................................680 Overloading a Class-Based Indexed Property...........................................684 Practical Learning: Overloading an Indexer.............................................693 Read/Write Indexed Properties...............................................................694 INTRODUCTION TO COLLECTIONS..................................................................697 ARRAY-BASED LISTS............................................................................................697 Setting Up a Collection.............................................................................697 The Number of Items in a Collection........................................................698 ROUTINE OPERATIONS ON AN ARRAY-BASED LIST...........................................................700 Adding an Item........................................................................................700 Getting an Item From a List.....................................................................701 Inserting an Item in the List....................................................................703 Removing an Item From the List..............................................................706 A COLLECTION OF ITEMS........................................................................................709 Practical Learning: Introducing Collections..............................................709 Implementing a Collection.......................................................................716 Practical Learning: Creating a Class Collection.........................................718 The Beginning of a Collection...................................................................718 Linking the Items of a Collection..............................................................719 Practical Learning: Creating a List's Monitor............................................720 OPERATIONS ON A COLLECTION.................................................................................721 Adding an Item........................................................................................721 Practical Learning: Adding Items to a Collection......................................722

C# 3.0 Practical Learning

11

Retrieving an Item...................................................................................723 Practical Learning: Retrieving the Items of a Collection...........................724 Removing an Item....................................................................................727 Practical Learning: Retrieving the Items of a Collection...........................728 Locating an Item......................................................................................732 ITERATING THROUGH A COLLECTION.............................................................736 ENUMERATING THE MEMBERS OF A COLLECTION..............................................................736 Introduction to System Collections..........................................................736 Practical Learning: Introducing Built-In Collections.................................736 Introduction to the IEnumerator Interface..............................................739 Practical Learning: Introducing Enumerations.........................................740 The Current Item of an Enumeration........................................................741 Practical Learning: Getting to the Current Item.......................................741 Resetting the Tag of the Current Item......................................................742 Practical Learning: Resetting the Tag of the Current Item.......................743 Moving to the Next Item in the Enumerator.............................................744 Practical Learning: Moving to the Next Item in the Enumerator...............745 AN ENUMERABLE COLLECTION..................................................................................746 Getting the Enumerator............................................................................746 Practical Learning: Getting the Enumerator.............................................747 Using foreach...........................................................................................748 Practical Learning: Using foreach on an Enumerator................................750 INTRODUCTION TO BUILT-IN COLLECTION CLASSES......................................753 OVERVIEW OF .NET COLLECTIONS............................................................................753 The ICollection Interface..........................................................................753 Introduction to the ArrayList Class...........................................................753 Practical Learning: Introducing the ArrayList Class..................................753 The Capacity of a List...............................................................................757 A Read-Only List.......................................................................................758 Item Addition...........................................................................................758 Practical Learning: Adding Items to an ArrayList List...............................759 The Number of Items in the List...............................................................771 Item Retrieval..........................................................................................771 Practical Learning: Retrieving Items From an ArrayList List.....................772 Item Location...........................................................................................794 Item Deletion...........................................................................................795 GENERICS.......................................................................................................796 GENERIC METHODS..............................................................................................796 Practical Learning: Introducing Generics.................................................797 Generic Method Creation..........................................................................800 Practical Learning: Creating a Generic Method.........................................800 Calling a Generic Method..........................................................................801 Practical Learning: Calling a Generic Method............................................802 A GENERIC METHOD WITH VARIOUS PARAMETERS..........................................................803 Practical Learning: Using a Method With Various Parameters..................804 A Generic Method With Various Parameter Types.....................................805 Calling a Generic Method With Various Parameter Types.........................806 GENERIC CLASSES...............................................................................................807 Practical Learning: Introducing Generic Classes......................................808 Using a Generic Class...............................................................................810 Passing a Parameter Type to a Method.....................................................812 Returning a Parameter Type.....................................................................812 Practical Learning: Returning a Parameter Type......................................813 A Property of the Parameter Type............................................................815 A GENERIC CLASS WITH MULTIPLE PARAMETERS...........................................................816 Using Multiple Type Parameters...............................................................816

C# 3.0 Practical Learning

12

A Class as a Parameter Type....................................................................818 GENERIC CLASSES AND INHERITANCE..........................................................................820 Generic Classes and Interfaces................................................................825 Constraining a Generic Class....................................................................826 INTRODUCTION TO FILE PROCESSING............................................................831 OVERVIEW OF FILE PROCESSING AND DEFINITIONS..........................................................831 Files.........................................................................................................831 Streams....................................................................................................831 STREAMING PREREQUISITES.....................................................................................832 Practical Learning: Introducing Streaming...............................................832 The Name of a File....................................................................................838 Practical Learning: Specifying the Name of a File.....................................839 The Path to a File.....................................................................................840 THE .NET SUPPORT FOR FILES...............................................................................842 File Existence...........................................................................................842 Practical Learning: Checking the Existence of a File.................................842 File Creation.............................................................................................844 Access to a File.........................................................................................845 File Sharing..............................................................................................845 The Mode of a File....................................................................................845 FUNDAMENTALS OF FILE STREAMING...........................................................................846 Practical Learning: Creating a Stream......................................................847 Stream Writing.........................................................................................848 Stream Closing.........................................................................................849 Practical Learning: Writing to a Stream....................................................849 Stream Reading........................................................................................852 Practical Learning: Reading From a Stream..............................................854 DETAILS ON FILE PROCESSING.......................................................................864 EXCEPTION HANDLING IN FILE PROCESSING..................................................................864 Finally......................................................................................................864 Practical Learning: Finally Releasing Resources.......................................866 .NET Framework Exception Handling for File Processing..........................876 Practical Learning: Handling File Processing Exceptions..........................878 FILE INFORMATION..............................................................................................886 Practical Learning: Introducing File Information......................................886 File Initialization......................................................................................889 File Creation.............................................................................................889 File Existence...........................................................................................890 Writing to a File........................................................................................891 Practical Learning: Writing to a File.........................................................891 Appending to a File...................................................................................892 Practical Learning: Appending to a File....................................................892 FILES OPERATIONS.........................................................................................895 ROUTINE OPERATIONS ON FILES...............................................................................895 Opening a File..........................................................................................895 Deleting a File..........................................................................................895 Copying a File...........................................................................................895 Moving a File............................................................................................896 CHARACTERISTICS OF A FILE....................................................................................897 The Date and Time a File Was Created ....................................................897 The Date and Time a File Was Last Accessed ...........................................898 The Name of a File....................................................................................898 The Extension of a File.............................................................................898 The Size of a File......................................................................................899 The Path to a File.....................................................................................900 The Attributes of a File.............................................................................900

C# 3.0 Practical Learning

13

DIRECTORIES.....................................................................................................900 Practical Learning: Introducing Directories..............................................901 Directory Creation....................................................................................902 Checking for a Directory Existence...........................................................903 Locating a File..........................................................................................903 Practical Learning: Using Directories and Files.........................................903 SERIALIZATION..............................................................................................916 OBJECT SERIALIZATION AND DE-SERIALIZATION.............................................................916 Practical Learning: Introducing Serialization...........................................919 Serialization.............................................................................................922 Practical Learning: Serializing an Object..................................................924 De-Serialization........................................................................................936 Practical Learning: De-Serializing an Object.............................................938 SOAP SERIALIZATION.........................................................................................941 Practical Learning: Introducing SOAP Serialization..................................941 Serialization With SOAP...........................................................................943 Practical Learning: Serializing With SOAP................................................945 De-Serialization With SOAP......................................................................947 Practical Learning: Deserializing With SOAP............................................948 DETAILS ON SERIALIZATION....................................................................................951 Partial Serialization..................................................................................951 Implementing a Custom Serialized Class..................................................954 .NET Built-In Serialized Classes................................................................954

C# 3.0 Practical Learning

14

1 - Introduction to C#
Introduction
C# is a Sharp 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 is used on many operating systems, including Microsoft Windows. 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.

Console Applications
The C# language is used to create applications that display on a black window referred to as the DOS prompt or DOS window. Those are the types of applications we will create in our lessons. To study the C# language, we will use Microsoft Visual C# 2008 Express Edition or Microsoft Visual C# 2008 Professional. To get Microsoft Visual C# 2008 Express Edition, you can download it free from the Microsoft web site. After downloading it, you can install it. To launch Microsoft Visual C# 2008 Express Edition, you can click Start -> (All) Programs -> Microsoft Visual C# 2008 Expression Edition:

To launch Microsoft Visual C# 2008 Professional, you can click Start -> (All) Programs -> Microsoft Visual Studio 2008. To create the type of applications we will study in our lessons, on the main menu, you can click File -> New Project... In the Templates section of the New Project dialog box, you can click Console Application, accept the default name or change it:

After clicking OK, a skeleton code would be created for you. Right now, we will not review every part of the code. Everything will be introduced and explained as we move on. C# 3.0 Practical Learning
16

Writing Code
Introduction
The programs we will write are meant to give instructions to the computer about what to do, when to do something, and how to do it. You write these instructions in an easy to understand English format, using words we will study. This means that a regular instruction uses normal text with alphabetic characters, numbers, and non-readable symbols. Normally, you can write your instructions using any text editor such as Notepad, WordPad, WordPerfect, or Microsoft Word, etc. When writing your instructions, there are rules your must follow and suggestions you should observe. We sill study each one of them as we move on. The group of instructions used by your program is also referred to as code. To assist you with writing code, Microsoft Visual C# 2008 includes a text editor referred to as the Code Editor. This is the window that displays when you have just created a console application. Besides the Code Editor, the integrated development interface (IDE) of the Microsoft Visual C# 2008 is made of various parts, which we will review when necessary.

Practical Learning: Creating a Program
1. Start Microsoft Visual C# 2008 Express Edition or Microsoft Visual C# 2008 Professional 2. To create a new application, on the Start Page, on the right side of Create, click Project 3. In the Templates section, click Console Application 4. Change the Name to GeorgetownCleaningServices1 and click OK

Comments
A comment is a line or paragraph of text that will not be considered as part of your 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:
// 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. Therefore, you can use this technique to span a comment on more than one line.

Practical Learning: Creating Comments

C# 3.0 Practical Learning

17

1. To create comments, change the file as follows:
using System; // using System.Collections.Generic; // using System.Linq; // using System.Text; /* namespace GeorgetownCleaningServices1 {*/ class Program { static void Main(/* string[] args */) { } } //}

2. To save the project, on the Standard toolbar, click the Save All button

3. Accept the name as GeorgetownCleaningServices1 and click Save

Code Colors
Code is written in a wide area with a white background. This is the area you use the keyboard to insert code with common readable characters. The Code Editor uses some colors to differentiate categories of words or lines of text. The colors used are highly customizable. To change the colors, on the main menu, you can click Tools -> Options... In the Options dialog box, in the Environment section, click Fonts and Colors. To set the color of a category, in the Display Items section, click the category. In the Item Foreground combo box, select the desired color. If you want the words of the category to have a colored background, click the arrow of the Item Background combo box and select one:

C# 3.0 Practical Learning

18

In both cases, the combo boxes display a fixed list of colors. If you want more colors, you can click a Custom button to display the Color dialog box that allows you to "create" a color.

Indentation
Indentation is another feature that makes your program easy to read. Indentation is a technique of grouping lines of code by category. To delimit the items of your code, you should indent them by two empty spaces or one tab. Indentation should be incremental. That is, when a line of code appears to be a child of the previous line, the new line should be indented.

Solution and Project Management
A Project
We have seen how to create a console application. Microsoft Visual C# allows you to create various other types of applications. This is why you should first display the New Project dialog box to select your option. Besides console applications, in future lessons, we will start some applications with the Empty Project. We will also learn how to create a library using the Class Library option. We will ignore the other three options in this book. To control the indentation of your code, on the main menu, click Tools -> Options... In the left list, expand C#, followed by Formatting and click Indentation. Then change the options on the right side:

C# 3.0 Practical Learning

19

After making the changes, click OK to validate or Cancel to ignore.

Saving a Project
In previous versions of Microsoft Visual C# (namely 2002 and 2003), you always had to formally create a project in order to use one and you always had to save it. After realizing that many of the projects that developers or students create are for experimental purposes, Microsoft provided the ability to only temporarily create a project, then to save it or not. Saving a project allows you to keep on a medium so you can refer to it later. When Microsoft Visual Studio 2008 (any edition) is installed, it creates a folder named Visual Studio 2008 in your My Documents folder. The My Documents folder is called your personal drive or your personal directory. Inside of the Visual Studio 2008 folder, it creates a sub-folder named Projects. By default, this is where it would save your projects, each with its own folder. To save a project, on the Standard toolbar, you can click the Save All button . Alternatively, on the main menu, you can click File -> Save All. If the project had already been saved but you want to save it under a different name, on the main menu, you can click File -> Save project name As...

A Solution
A solution is used to coordinate the different aspects of an application that is being created. When you create a project, it represents one detail of the application you have in mind. Besides the code you are writing, you may want to add other items. Instead of one project, in the next sections, we will see that a solution can contain more than one project. When creating a project, the solution holds the same name as the project. You can see their names in the Solution Explorer: 20 C# 3.0 Practical Learning

The solution and a project can have different names. While working on a project, to rename the solution, in the Solution Explorer, you can click the first node, which is the name of the solution starting with Solution. Then, in the Properties window, click (Name) and type the name of your choice:

This name is temporary, especially if you have not yet saved the project. If you want to permanently save a solution for later use, there are two techniques you can use. If you start saving a project for the first time, it would bring the Save Project dialog box. By default, Microsoft Visual Studio selects your personal directory as the path to the solution. This is called the location. In the location, Microsoft Visual Studio creates a folder as the solution of the project. The solution must have, or must be stored, in its own folder. As mentioned earlier, Microsoft Visual Studio uses the name of the project as the name of the solution. To rename the solution, you can change the string in the Solution Name text box. Remember that you can enter the name of the project in the Name text box. Here is an example:

C# 3.0 Practical Learning

21

When you save a project (for the first time), by default, Microsoft Visual C# creates a new folder for it in the My Documents\Visual Studio 2008\Projects folder. It uses the name of the solution to name the folder. It creates some files and stores them in that new folder. Then, it creates a sub-folder, using the name of the project, inside of the folder of the solution. Besides the sub-folder with the name as the project, it creates another folder named debug. It also creates another folder named Debug in the sub-folder of the name of the project. In each folder and some other folders, it creates some files that we will not pay attention to for now. If the project had already been saved but you want to change the name of the solution, on the main menu, you can click File -> Save solution-name.sln As... This would bring the Save File As dialog box where you can specify the name of the solution and click Save.

Executing a Project
After creating a project and writing code, you may want to see the result. To do this, you must execute the application. This would create an executable that you can use on other computers and that you can distribute to other people. To execute an application, on the main menu, you can click Debug -> Start Without Debugging. Instead of going through the main menu every time, you can add the Start Without Debugging button to a toolbar. To do this, you can right-click any toolbar and click Customize... In the Commands property page of the Customize dialog box, you can click Debug in the Categories click, then drag Start Without Debugging, and drop it on a toolbar. Here is an example:

C# 3.0 Practical Learning

22

After adding the button(s), you can click Close. The next time you want to execute an application, you can just click this button.

Practical Learning: Executing an Application
1. To execute the application, on the main menu, click Debug -> Start Without Debugging 2. After viewing the result in a DOS window, press Enter to close it

Adding a Project
One of the most valuable features of Microsoft Visual Studio 2005 is that it allows you to work on more than one project without launching more than one instance of the studio. This means that you can add a project to another project you are working on and treat each as a separate entity.

C# 3.0 Practical Learning

23

Before adding one project to another, you must save, or you must have saved, the current project. To add a project, in the Solution Explorer, you can rightclick the most top node (it starts with Solution) and position the mouse on Add:

If you have a project that was previously saved but you don't want to open a separate instance of Microsoft Visual Studio for it, you can click Existing Project... This would bring the Add Existing Project dialog box that allows you to select a project from a folder. To add a new project, after right-clicking, you can click New Project... If you add a new project, and if you want to keep it for future references, you must save it. To save the new project, you can click the Save All button on the Standard toolbar. After saving the new project, a folder with its name would be created inside of the folder of the solution. On the right side of the name of the solution in Solution, the number of its projects is specified in parentheses, as 1 project, or 2 projects, etc. After adding a project, each would be represented by its own node in the Solution Explorer and in the Class View. Here is an example:

C# 3.0 Practical Learning

24

Also, a sub-folder for each project is created in the folder of the solution:

In the Solution, the name of one of the projects, if there is more than one, is in bold characters. This project is called the StartUp Project. If, on the main menu, you click Debug -> Start Without Debugging, the project in bold characters would be executed. If you want to change the start up project, you can rightclick its node and click Set As StartUp Project.

C# 3.0 Practical Learning

25

2 - INTRODUCTION TO VARIABLES
Variables
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.

Practical Learning: Introducing Variables
1. Start Microsoft Visual C# 2008 Express Edition or Microsoft Visual C# 2008 Professional From now on, we will only refer to Microsoft Visual C# 2. To create a new application, on the Start Page, on the right side of Create, click Project 3. In the Templates section, click Console Application 4. Change the Name to GeorgetownCleaningServices2 and click OK

Names in C#
C# 3.0 Practical Learning
26

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 interface internal

out override

short

typeof
uint

as
base bool break byte case catch char

continue false decimal default finally

sizeof

params
private

stackalloc ulong
static

fixed

is lock
long namespace new null object

unchecked
unsafe ushort using virtual void

delegate float do double else enum for foreach goto if

protected string public readonly ref return sbyte sealed struct switch this throw true try

checked event
class

implicit
in

volatile
while

explicit

operator

Besides these keywords, C# has other words that should be reserved only depending on how and where they are used. These are referred to as contextual keywords and they are:
get partial set value where

yield

Once you avoid these words, there are rules you must follow when naming your objects. On this 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 C# 3.0 Practical Learning
27

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, main is always written Main.

Values and Variables on the Console
As mentioned already, the applications we will create display in a dark object called the DOS window. Here is an example showing some values:

To display a value in this window, you can enter it in the parentheses of the Console.Write() or Console.WriteLine(). Here are two examples:
using System; class Program { static void Main() { Console.WriteLine(248); Console.Write(1); } }

If you write Console.WriteLine() with empty parentheses, an empty line would be displayed. In future lessons, we will learn what the meanings of Console, Write(), and WriteLine().

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 C# 3.0 Practical Learning
28

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 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. C# 3.0 Practical Learning
29

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, 279, 917293, 39473 Non- Decimal Values: 0237, 0276382, k2783, R3273 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 * 10 1 + 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: Add 0 to the preceding 100000 10000 1000 1000 100 10 0 value 0 0 0

etc

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
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? C# 3.0 Practical Learning
30

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 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, his home address, 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. 31 C# 3.0 Practical Learning

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. 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, you have two options:

If you know the type of variable you want to use, you can provide it followed by the name of the variable. Based on this, one syntax used to declare a variable is:
DataType VariableName;

As an alternative, you can provide only a name for the variable but let the compiler specify its data type. To declare such a variable, you use the var keyword followed by the name of the variable. This certainly would not be enough. For the compiler to know how much space is necessary, you must provide a value for the variable

Providing a value for a variable is referred to as initializing it. This can be done for declared with either a data type or the var keyword:
• •

If you declare a variable using data type, the initialization could be optional (depending on how you will access the variable) If you declare a variable using the var keyword, you must initialize it

To initialize a variable, on the right side of its name, type the assignment operation, which is =, followed by a value:

If you declare a variable using a data type, you must initialize it with an appropriate value. When we study the data type, we will see what value is appropriate for what data type If you declare a variable using the var keyword, you can initialize it with almost any type of value (of course there are exceptions). The purpose of using the var keyword is to let the compiler decides what type the variable is. To make this decision, the compiler refers to the type of value the variable was assigned with. For illustrative purposes, in many lessons, we will use the var keyword to declare variables. In practicality, don't abuse or overuse the var keyword. It can be confusing. The beauty of var, which is one of its rules, is that you MUST initialize its variable. This makes it possible to know the type of variable you are using. On the other hand, if you declare too many variables with var and initialize them with the same types of values, you C# 3.0 Practical Learning
32

could get confused with the type of data that each of those variables is holding. So, use the var keyword sparingly: It can be a beauty but, if overused, it can be confusing. The good news is that the compiler knows exactly what it is doing and what it is asked to do.

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:

0

1

You can represent a piece of information with one of two states. This technique of representing values is the same as the binary system. 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 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:

C# 3.0 Practical Learning

33

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 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. C# 3.0 Practical Learning
34

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 Binary Hexadecimal

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111

0 1 2 3 4 5 6 7 8 9 A B C D E F

Table of Numeric Conversions

C# 3.0 Practical Learning

35

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:
Decimal Minimum Maximum Hexadecimal Binary

0 15

0x0 0xf

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
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.

C# 3.0 Practical Learning

36

If you have the patience to create combinations of bits using the boxes 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 + 26 + 25 + 24 + 23 + 22 + 21 + 20 = 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255 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:
Decimal Minimum Maximum Hexadecimal Binary

0 255

0x0 0xff

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'); } }

C# 3.0 Practical Learning

37

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, you can use the var keyword and initialize the variable with a character in single-quotes. Here is an example:
using System; class Exercise { static void Main() { var Gender = 'F'; Console.Write("Student Gender: "); Console.WriteLine(Gender);

} }

Alternatively, you can use the char keyword. Here is an example:
using System; class Exercise { static void Main() { char Gender = 'M'; Console.Write("Student Gender: "); Console.WriteLine(Gender); } }

This would produce:
Student Gender: M

Escape Sequences
An escape sequence is a special character that displays non-visibly. For example, you can use this type of character to indicate the end of line, that is, to ask the program to continue on the next line. An escape sequence is represented by a backslash character, \, followed by another character or symbol. For example, the escape sequence that moves to the next line is \n. 38 C# 3.0 Practical Learning

An escape can be included in single-quotes as in '\n'. It can also be provided in double-quotes as "\n". The C# language recognizes other escape sequences.
Escape Sequence Name Description

\a \b \t

Bell (alert) Backspace Horizontal Tab New line

Makes a sound from the computer Takes the cursor back Takes the cursor to the next tab stop Takes the cursor to the beginning of the next line

\n \v \f \r

Vertical Tab Performs a vertical tab Form feed Carriage return Double Quote Causes a carriage return

\" \' \? \\ \0

Displays a quotation mark (")

Apostrophe Displays an apostrophe (') Question mark Backslash Null Displays a question mark Displays a backslash (\) Displays a null character

To use an escape sequence, you can also first declare a char variable and initialize it with the desired escape sequence in single-quotes.

The Byte Data Type
A byte is an unsigned number whose value can range from 0 to 255 and therefore can be stored in one byte. You can use it when you know a variable 39 C# 3.0 Practical Learning

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. Alternatively, you can also use the var keyword to declare the variable and initialize it with a small number. Here is an example:
using System; class Exercise { static void Main() { var Age = 14; Console.Write("Student Age: "); Console.WriteLine(Age); Age = 12; Console.Write("Student Age: "); Console.WriteLine(Age);

} }

Instead of a decimal number, you can also initialize an integral variable with a hexadecimal value. When doing this, make sure the decimal equivalent is less than 255. Here is an example:
using System; class Exercise { static void Main() {

C# 3.0 Practical Learning

40

var Number = 0xFE; Console.Write("Number: "); Console.WriteLine(Number);

} }

This would produce:
Number: 254 Press any key to continue . . .

Practical Learning: Using Bytes
1. Change the Program.cs file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GeorgetownCleaningServices2 { class Program { static void Main(string[] args) { byte Shirts; byte Pants; Shirts = 4; Pants = 1; Console.WriteLine("-/- Georgetown Cleaning Services -/-"); Console.WriteLine("========================"); Console.WriteLine("Item Type Qty"); Console.WriteLine("------------------------"); Console.Write("Shirts "); Console.WriteLine(Shirts); Console.Write("Pants "); Console.WriteLine(Pants); Console.WriteLine("========================"); Console.WriteLine(); }

} }

2. Execute the program. This would produce:
-/- Georgetown Cleaning Services -/======================== Item Type Qty -----------------------Shirts 4 Pants 1 ========================

C# 3.0 Practical Learning

41

3. Close the DOS window

Signed Byte
A byte number is referred to as signed if it can hold a negative of 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
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 42 C# 3.0 Practical Learning

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 = 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. To declare a variable for such a value, you can use the var keyword and initialize the variable with a value between –32768 to 32767. Here is an example:
using System; class Exercise { static void Main() { var SchoolEffective = 1400; // Number of Students Console.Write("School Effective: "); Console.WriteLine(SchoolEffective);

C# 3.0 Practical Learning

43

} }

This would produce:
School Effective: 1400 Press any key to continue . . .

Since the byte is used for characters and very small numbers, whenever you plan to use a number in your program, the minimum representation you should use is a word. A natural number is also called an integer. If you want to declare the variable using a data type, the smallest integer you can store in a word is declared with the short keyword. 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 Exercise { 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 either the var of 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 {

C# 3.0 Practical Learning

44

static void Main() { // These variables must hold only positive integers ushort NumberOfTracks; 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 using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GeorgetownCleaningServices2 { class Program { static void Main(string[] args) { byte Shirts; byte Pants; ushort OtherItems; Shirts = 4; Pants = 1; OtherItems = 3; Console.WriteLine("-/- Georgetown Cleaning Services -/-"); Console.WriteLine("========================"); Console.WriteLine("Item Type Qty"); Console.WriteLine("------------------------"); Console.Write("Shirts "); Console.WriteLine(Shirts); Console.Write("Pants "); Console.WriteLine(Pants); Console.Write("Other Items "); Console.WriteLine(OtherItems); Console.WriteLine("========================"); Console.WriteLine();

C# 3.0 Practical Learning

45

} } }

2. Execute the program. This would produce:
-/- Georgetown Cleaning Services -/======================== Order Date: 7/15/2002 -----------------------Item Type Qty -----------------------Shirts 4 Pants 1 Other Items 3 ======================== Press any key to continue . . .

3. Close the DOS window

C# 3.0 Practical Learning

46

3 – USING VARIABLES
A Double-Word
Introduction
A double-word is a group of two consecutive Words. This means that a doubleword 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:

2n1

230

229

228

227

226

225

224

et 1,073,741,8 536,870,9 268,435,4 134,217,7 67,108,86 33,554,43 16,777,21 c 24 12 56 28 4 2 6

223

222

221

220

219

218

217

216
47

C# 3.0 Practical Learning

8,388,60 4,194,30 2,097,15 1,048,57 524,288 262,144 131,072 8 4 2 6

65,536

215 32,768

214 16,384

213 8,192

212 4,096

211 2,048

210 1,024 512

29

28 256

27 128 64

26 32

25 16

24 8

23 4

22 2

21

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

C# 3.0 Practical Learning

48

To declare a variable that can hold large values, you can use the var keyword and initialize the variable with the desired value. Here is an example:
using System; class Exercise { static void Main() { var Population = 72394475; Console.Write("Country Population: "); Console.WriteLine(Population); } }

This would produce:
Country Population: 72394475 Press any key to continue . . .

Practical Learning: Using Unsigned Integers
1. Start Microsoft Visual C# 2. To create a new application, on the main menu, click File -> New -> Project... 3. In the Templates section, click Console Application 4. Change the Name to GeorgetownCleaningServices3 and click OK 5. Change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GeorgetownCleaningServices3 { class Program { static void Main(string[] args) { byte Shirts; byte Pants; ushort OtherItems; Shirts = 4; Pants = 0; OtherItems = 3; Console.WriteLine("-/- Georgetown Cleaning Services -/-"); Console.WriteLine("========================"); Console.WriteLine("------------------------"); Console.WriteLine("Item Type Qty");

C# 3.0 Practical Learning

49

Console.WriteLine("------------------------"); Console.Write("Shirts "); Console.WriteLine(Shirts); Console.Write("Pants "); Console.WriteLine(Pants); Console.Write("Other Items "); Console.WriteLine(OtherItems); Console.WriteLine("========================"); Console.WriteLine(); } } }

6. Execute the program to see the result 7. Close the DOS window

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, besides the var keyword, you can 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 Exercise { 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)

If you declare an integer variable using the var keyword and initialize it with a value lower than 2,147,484,647, the compiler concludes that the memory needed to store that variable is 32 bits: C# 3.0 Practical Learning
50

When initializing an integral variable, instead of a decimal number, you can also initialize it with a hexadecimal value whose decimal equivalent is less than 2,147,484,647. Here is an example:
using System; class Exercise { static void Main() { var Number = 0xF0488EA; Console.Write("Number: "); Console.WriteLine(Number); } }

This would produce:
Number: 251955434 Press any key to continue . . .

Unsigned Integers
If the variable must hold only positive natural numbers, you can declared it using the uint keyword. The uint keyword is used to identify a 32-bit positive integer whose value would range from 0 to 2,147,484,647. Here is an example:
using System; class Exercise { static void Main() {

C# 3.0 Practical Learning

51

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

Practical Learning: Using Unsigned Integers
1. To use unsigned variables, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GeorgetownCleaningServices3 { class Program { static void Main(string[] args) { byte Shirts; byte Pants; ushort OtherItems; uint OrderDay; uint OrderMonth; uint OrderYear; Shirts = 4; Pants = 0; OtherItems = 3; OrderDay = 15; OrderMonth = 7; OrderYear = 2002; Console.WriteLine("-/- Georgetown Cleaning Services -/-"); Console.WriteLine("========================");

C# 3.0 Practical Learning

52

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(Shirts); Console.Write("Pants "); Console.WriteLine(Pants); Console.Write("Other Items "); Console.WriteLine(OtherItems); Console.WriteLine("========================"); Console.WriteLine(); } } }

2. Execute the program. This would produce:
-/- Georgetown Cleaning Services -/======================== Order Date: 7/15/2002 -----------------------Item Type Qty -----------------------Shirts 4 Pants 0 Other Items 3 ======================== Press any key to continue . . .

3. Close the DOS window

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. If you declare an integer variable using the var keyword and initialize it with a value between 2,147,484,647 and 9,223,372,036,854,775,807, the compiler concludes that the memory needed to store that variable is 64 bits:

C# 3.0 Practical Learning

53

Long Integers
If you want to use a variable that can hold very large numbers that would require up to 64 bits, you can declare it using either the var or the long keyword. In C++, the long data type is 32 bits while in C#, the long data type is 64 bits. As stated previously, if you initialize the variable with a value lower than 2,147,484,647, the compiler would allocate 32 bits of memory for it. If you initialize the variable with a value between 2,147,484,647 and 9,223,372,036,854,775,807, the compiler would allocate 64 bits of memory for it. If the value is higher than 9,223,372,036,854,775,807, which is too large, the compiler would present an error:

C# 3.0 Practical Learning

54

This means that you should limit the values assigned to integral variables to 64 bits, which is very significant. Here is an example that uses the long data type:
using System; class Exercise { static void Main() { var CountryArea = 5638648; Console.Write("Country Area: "); Console.Write(CountryArea); Console.Write("km2\n"); } }

This would produce:
Country Area: 5638648km2 Press any key to continue . . .

As mentioned for other integral types, you can initialize a long variable with a hexadecimal value. Although the long data type is used for large number, it mainly indicates the amount of space available but you do not 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 would allocate the appropriate amount of space to accommodate the values of the variable. Consequently, the amount of space C# 3.0 Practical Learning
55

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 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:

C# 3.0 Practical Learning

56

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.

Floating-Point Numbers
The integers we have used so far have the main limitation of not allowing decimal values. C# provides floating values that would solve this problem. The most fundamental floating variable is declared with the float keyword. A variable declared a 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

C# 3.0 Practical Learning

57

When a variable is larger than the float can handle and requires more precision, you should declare it using either the var or the the double keyword. Here is an example:
using System; class Exercise { static void Main() { var Number = 62834.9023; Console.Write("Number: "); Console.WriteLine(Number);

} }

This would produce:
Number: 62834.9023 Press any key to continue . . .

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. Because the double data type provides a better result with a better precision than the float, whenever you declare a variable using either the var or the float keyword and assign it a value, 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 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

Remember that if you declare the variable as var and want to treat it as a value with single precision, add an F suffix to the value assigned to it. Here is an example:
using System; class Exercise { static void Main()

C# 3.0 Practical Learning

58

{ var Number = 62834.9023F; Console.Write("Number: "); Console.WriteLine(Number); } }

On the other hand, if you want a value to be treated with double-precision, add a D suffix to it. Here is an example:
using System; class Exercise { static void Main() { var Number = 62834.9023D; Console.Write("Number: "); Console.WriteLine(Number); } }

Practical Learning: Using a Double-Precision Variable
1. To use a double-precision value, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GeorgetownCleaningServices3 { class Program { static void Main(string[] args) { byte Shirts; byte Pants; ushort OtherItems; uint OrderDay; uint OrderMonth; uint OrderYear; double MondayDiscount; Shirts = 4; Pants = 0; OtherItems = 3; OrderDay = 15; OrderMonth = 7; OrderYear = 2002; MondayDiscount = 0.25D; // 25% Console.WriteLine("-/- Georgetown Cleaning Services -/-");

C# 3.0 Practical Learning

59

} } }

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(Shirts); Console.Write("Pants "); Console.WriteLine(Pants); Console.Write("Other Items "); Console.WriteLine(OtherItems); Console.WriteLine("------------------------"); Console.Write("Monday Discount: "); Console.Write(MondayDiscount); Console.WriteLine('%'); Console.WriteLine("========================"); Console.WriteLine();

2. Execute the application to see the result:
-/- Georgetown Cleaning Services -/======================== Order Date: 7/15/2002 -----------------------Item Type Qty -----------------------Shirts 4 Pants 0 Other Items 3 -----------------------Monday Discount: 0.25% ======================== Press any key to continue . . .

3. Close the DOS window

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. To indicate that the variable holds a decimal value, when initializing it, add an M suffix to its value. Here is an example: C# 3.0 Practical Learning
60

using System; class NumericRepresentation { static void Main() { decimal HourlySalary; HourlySalary = 24.25M; Console.Write("Hourly Salary = "); Console.WriteLine(HourlySalary); Console.WriteLine(); } }

This would produce:
Hourly Salary = 24

As seen in previous sections and this one, when declaring and initializing a real variable, the suffix you give to its assigned value indicates to the compiler the actual type of value and the type of memory that would be allocated for the variable:

If the value receives an F suffix, it is considered a floating point number with single precision

If the value receives a D suffix, it is considered a floating point number with double precision C# 3.0 Practical Learning
61

If the value receives an M suffix, it is considered a large decimal number

C# 3.0 Practical Learning

62

Practical Learning: Using Decimal Values
1. To use decimal variables, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GeorgetownCleaningServices3 { class Program { static void Main(string[] args) { byte Shirts; decimal PriceOneShirt; byte Pants; decimal PriceAPairOfPants; ushort OtherItems; decimal PriceOtherItems; uint OrderDay; uint OrderMonth; uint OrderYear; double MondayDiscount; Shirts = 5; PriceOneShirt = 0.95M; Pants = 2; PriceAPairOfPants = 1.95M; OtherItems = 3; PriceOtherItems = 4.55M; OrderDay = 15; OrderMonth = 7; OrderYear = 2002; MondayDiscount = 0.25D; // 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 Unit Price"); Console.WriteLine("------------------------"); Console.Write("Shirts "); Console.Write(Shirts); Console.Write(" "); Console.WriteLine(PriceOneShirt); Console.Write("Pants "); Console.Write(Pants);

C# 3.0 Practical Learning

63

} } }

Console.Write(" "); Console.WriteLine(PriceAPairOfPants); Console.Write("Other Items "); Console.Write(OtherItems); Console.Write(" "); Console.WriteLine(PriceOtherItems); 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 -/======================== Order Date: 7/15/2002 -----------------------Item Type Qty Unit Price -----------------------Shirts 5 0.95 Pants 2 1.95 Other Items 3 4.55 -----------------------Monday Discount: 0.25% ======================== Press any key to continue . . .

3. Close the DOS window

Accessory Data Types
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 Console.Write() to display it on the console. Here is an example:
using System; class Exercise { static void Main()

C# 3.0 Practical Learning

64

{ } } Console.WriteLine("Welcome to the World of C# Programming!");

This would produce:
Welcome to the World of C# Programming! Press any key to continue . . .

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 either the var or the string keyword followed by a name for the variable. The name will follow the rules we defined above. When declaring a string variable, you can initialize it with 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 two examples:
using System; class Exercise { static void Main() { var Team = "Real Madrid"; string Country = "Guinée Equatoriale"; Console.WriteLine("Welcome to the World of C# Programming!"); Console.Write("Team: "); Console.WriteLine(Team); Console.Write("Country: "); Console.WriteLine(Country); Console.WriteLine(); } }

This would produce:
Welcome to the World of C# Programming! Team: Real Madrid Country: Guinée Equatoriale Press any key to continue . . .

Practical Learning: Using Strings
1. To use strings, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GeorgetownCleaningServices3 { class Program { static void Main(string[] args)

C# 3.0 Practical Learning

65

{ string CustomerName; string CustomerHomePhone; byte Shirts; decimal PriceOneShirt; byte Pants; decimal PriceAPairOfPants; ushort OtherItems; decimal PriceOtherItems; uint OrderDay; uint OrderMonth; uint OrderYear; double MondayDiscount; CustomerName = "Gregory Almas"; CustomerHomePhone = "(301) 723-4425"; Shirts = 5; PriceOneShirt = 0.95M; Pants = 2; PriceAPairOfPants = 1.95M; OtherItems = 3; PriceOtherItems = 4.55M; OrderDay = 15; OrderMonth = 7; OrderYear = 2002; MondayDiscount = 0.25D; // 25% Console.WriteLine("-/- Georgetown Cleaning Services -/-"); Console.WriteLine("========================"); Console.Write("Customer: "); Console.WriteLine(CustomerName); Console.Write("Home Phone: "); Console.WriteLine(CustomerHomePhone); 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"); Console.WriteLine("------------------------"); Console.Write("Shirts "); Console.Write(Shirts); Console.Write(" "); Console.WriteLine(PriceOneShirt); Console.Write("Pants "); Console.Write(Pants); Console.Write(" "); Console.WriteLine(PriceAPairOfPants); Console.Write("Other Items "); Console.Write(OtherItems); Console.Write(" "); Console.WriteLine(PriceOtherItems); Console.WriteLine("------------------------"); Console.Write("Monday Discount: "); Console.Write(MondayDiscount);

C# 3.0 Practical Learning

66

Console.WriteLine('%'); Console.WriteLine("========================"); Console.WriteLine(); } } }

2. Execute the program. This would produce:
-/- Georgetown Cleaning Services -/======================== Customer: Gregory Almas Home Phone: (301) 723-4425 Order Date: 7/15/2002 -----------------------Item Type Qty Unit Price -----------------------Shirts 5 0.95 Pants 2 1.95 Other Items 3 4.55 -----------------------Monday Discount: 0.25% ======================== Press any key to continue . . .

3. Close the DOS window

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.
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
C# 3.0 Practical Learning
67

The object data type is used to declare a variable whose type is not primarily defined and can be any of the other data types we have introduced. After creating an object variable, you can use its value as you see fit. For example, you can enter the variable in the parentheses of Console.Write() or Console.WriteLine() to display it in the console window. Here is an example:
using System; class Exercise { static void Main() { var EmployeeName = "Ernestine Lamb"; object Address = "10244 Lockwood Drive"; Console.Write("Employee Name: "); Console.WriteLine(EmployeeName); Console.Write("Home Address: "); Console.WriteLine(Address); Console.WriteLine(); } }

This would produce:
Employee Name: Ernestine Lamb Home Address: 10244 Lockwood Drive Press any key to continue . . .

A variable declared with object can embrace almost any value. This means that, when initializing the variable, you can use any of the types of values we have seen so far. Here are examples:
using System; class Program { static void Main() { object PropertyNumber = "293749"; object PropertyType = 'S'; object Stories = 3; object Bedrooms = 4; object Value = 425880; Console.WriteLine("=//= Altair Realty =//="); Console.WriteLine("Properties Inventory"); Console.Write("Property #: "); Console.WriteLine(PropertyNumber); Console.Write("Property Type: "); Console.WriteLine(PropertyType); Console.Write("Stories: "); Console.WriteLine(Stories); Console.Write("Bedrooms: "); Console.WriteLine(Bedrooms); Console.Write("Market Value: "); Console.WriteLine(Value); } }

C# 3.0 Practical Learning

68

This would produce:
=//= Altair Realty =//= Properties Inventory Property #: 293749 Property Type: S Stories: 3 Bedrooms: 4 Market Value: 425880 Press any key to continue . . .

Constants
Custom Constants
Suppose you intend to use a number such as 39.37 over and over again. Here is an example:
using System; class Exercise { static void Main() { double Meter, Inch; Meter = 12.52D; Inch = Meter * 39.37D; Console.Write(Meter); Console.Write("m = "); Console.Write(Inch); Console.WriteLine("in\n");

} }

Here is an example of running the program:
12.52m = 492.9124in

If you use this 39.37 many times in your program, at one time, you may make a mistake and type it as 3937 or 3.937 or else. Consider the following program:
using System; class Exercise { static void Main() { double Meter, Inch; Meter = 12.52D; Inch = Meter * 39.37; Console.Write(Meter); Console.Write("m = "); Console.Write(Inch); Console.WriteLine("in\n");

C# 3.0 Practical Learning

69

Meter = 12.52D; Inch = Meter * 3.937; Console.Write(Meter); Console.Write("m = "); Console.Write(Inch); Console.WriteLine("in\n"); Meter = 12.52D; Inch = Meter * 393.7; Console.Write(Meter); Console.Write("m = "); Console.Write(Inch); Console.WriteLine("in\n");

} }

This would produce:
12.52m = 492.9124in 12.52m = 49.29124in 12.52m = 4929.124in

Because of mistakes in the way to represent the number, the same calculation produces different results. To make sure that this is unlikely, you can instead use a variable that holds the value. Then, when you need that value, you can access the variable instead of the value itself. A number such as 39.37 is called a constant. A constant is a value that never changes such as 244, "ASEC Mimosa", 39.37, or True. These are constant values you can use in your program any time. You can also declare a variable and make it a constant; that is, use it so that its value is always the same. To create a constant, type the const keyword to its left. When declaring a constant, you must initialize it with an appropriate value. Here is an example:
const double ConversionFactor = 39.37D;

Once a constant has been created and it has been appropriately initialized, you can use its name where the desired constant would be used. Here is an example of a constant variable used various times:
using System; class Exercise { static void Main() { const double ConversionFactor = 39.37D; double Meter, Inch; Meter = 12.52D; Inch = Meter * ConversionFactor; Console.Write(Meter); Console.Write("m = "); Console.Write(Inch);

C# 3.0 Practical Learning

70

Console.WriteLine("in\n"); Meter = 12.52D; Inch = Meter * ConversionFactor; Console.Write(Meter); Console.Write("m = "); Console.Write(Inch); Console.WriteLine("in\n"); Meter = 12.52D; Inch = Meter * ConversionFactor; Console.Write(Meter); Console.Write("m = "); Console.Write(Inch); Console.WriteLine("in\n"); } }

This would produce:
12.52m = 492.9124in 12.52m = 492.9124in 12.52m = 492.9124in

Notice that, this time, the calculation is more accurate. Also, this time, if you mistype the name of the variable in an operation, you would receive a compiler error, giving you the time to fix it. To initialize a constant variable, the value on the right side of the assignment operator "=" must be a constant or a value that the compiler can determine as constant. Instead of using a known constant, you can also assign it another variable that has already been declared as constant.

Built-in Constants
There are two main categories of constants you will use in your programs. You can create your own constant as we saw above. The C# language also provides various constants. Some constants are part of the C# language. Some other constants are part of the .NET Framework. Before using a constant, of course, you must first know that it exists. Second, you must know how to access it. A constant that is part of the C# language can be accessed anywhere in your code. Those constant are normally defined in the System namespace. Other constant are defined in various appropriate namespaces.
null: The null keyword is a constant used to indicate that a variable doesn't

hold a known value

PI: PI is a constant used as the ratio of the circumference of a circle to its diameter. PI is defined in Math. To use it, you would type Math.PI.

C# 3.0 Practical Learning

71

C# 3.0 Practical Learning

72

4 - INTRODUCTION TO CLASSES
Fundamentals of Classes
Introduction
In the previous two lessons, to use a variable, we were declaring it using either var or a known and simple data type. For example, we could use an integer to declare a variable that represented the number of bedrooms of a house. Here is an example:
using System; class Program { static void Main() { int bedrooms = 3; } }

As opposed to a simple variable, in C#, you can use one or more variables to create a more complete or complex object. Instead of only one file, you can create a program with many of them. Each file can contain different instructions that, when put together, can create an application as complete as possible. To create a code file, on the main menu, you can click Project -> Add New Item... In the Templates list, click Code File, accept or change the name of the file. You can omit the .cs extension. If you do, a file with the extension .cs would be added.

Practical Learning: Introducing Classes
1. Start Microsoft Visual C# 2. Create a Console Application named DepartmentStore1 3. Execute the application to see the result 4. Close the DOS window

Creating a Class
C# 3.0 Practical Learning
73

A class is a technique of using one or a group of variables to be used as a foundation for a more detailed variable. 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 House:
class House { }

A class is created in a code file. As such, you can include it in the first file of your project. Here is an example:
using System; class House { } class Program { static void Main() { int bedrooms = 3; } }

You can also create a class in its own file. To assist you with this, Microsoft Visual C# provides a wizard. To use it, on the main menu, you can click Project -> Add Class... or Project -> Add New Item... In the Templates list, click Class. In the Name text box, accept or change the default name and click Add. A new file named after the class with the .cs extension would be added to your project. When a project is made of various files, each file is represented by a tab in the top section of the Code Editor:

C# 3.0 Practical Learning

74

To access a file, you can click its tab.

Practical Learning: Introducing Classes
1. To create a new class, on the main menu, click Project -> Add Class... 2. In the Add New Item dialog box, change the name to DepartmentStore and click Add

Visually Managing Classes
To assist you with managing the various classes of a project, Microsoft Visual C# includes various tools and windows. One of the windows you can use is called the Class View. To display it, on the main menu, you can click View -> Class View:

C# 3.0 Practical Learning

75

The Class View is made of four sections. The toolbar under the title bar includes four buttons. To identify a button, you can position the mouse on it and a tool tip would appear. Under the toolbar, another bar made of a combo box and a button allow you to search. The main top section of the Class View is made of various nodes. To expand a node, you can click its + button. To collapse a node, you can click its - button. The top node displays the name of the project. Under the project node, the names of classes display. The bottom section of the Class View is used to display the members of a class. To see the members of a class, you can click it in the top window. Here is an example:

To add a new class, besides the main menu, you can right-click the name of the project in the Class View, position the mouse on Add, and click Class...

Declaring a Variable of a Class Type
Like any normal variable, to use a class in your program, you can first declare a variable for it. Like the variables we introduced in the previous lesson, to declare a variable of a class, you can use the var keyword. Alternatively, you C# 3.0 Practical Learning
76

can type its name followed by a name for the variable. For example, to declare a variable of the above House class, you could type the following:
using System; class House { } class Program { static void Main() { var property . . . } }

Or the following:
using System; class House { } class Program { static void Main() { House property; } }

The variables we have declared so far are called value variables. This is because such variables of primitive types hold their value. The C# language supports another type of variable. This time, when you declare the variable, its name does not hold the value of the variable; it holds a reference to the address where the actual variable is stored in memory. 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 House { } class Program { static void Main() { var Property = new House(); } }

C# 3.0 Practical Learning

77

If you are using the name of the class instead of var to declare the variable, you can first declare it. Then, on another line, you can allocate memory for it using the new operator. Here is an example:
using System; class House { } class Program { static void Main() { House Property; // You can do something here } } Property = new House();

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 files of the same project.

Sharing a Class
Unlike its sisters the C and the C++ languages, C# was developed with the idea of working complementarily with other languages such as C++/CLI, 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() { var Number = 244; var Thing = "Vehicle"; Console.WriteLine(Number); Console.WriteLine(Thing);

} }

Garbage Collection
When you initialize a variable using the new operator, you are in fact reserving some space in the heap memory. The memory is "allocated" for the variable. 78 C# 3.0 Practical Learning

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 "cleaning" the memory after you. This is done automatically when necessary so that the programmer doesn't need to worry about this issue.

Class' Fields
Introduction
Consider a class named House:
public class House { }

The section between the curly brackets, { and }, 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 house, declared as the parts of the above Book class and each declared as a variable:
public class House { string PropertyNumber; char PropertyType; byte Stories; uint bedrooms; decimal Value; }

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. 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:

C# 3.0 Practical Learning

79

Stock #: 437876 Stock #: 792475 Women Scoop Neck Dress Men Lightweight Jacket Unit Price: $148.00 Unit Price: $185

Stock #: 740797 Girls Velour Active Skirt Unit Price: $22.85

Stock: Women Leather $75.00

681432 Stock #: Python Print Men Escalade Bag Shoes $89.85

759470 Slip-On

Stock #: 482746 Boys Leather Bomber Jacket $255.50

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 using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore1 { class DepartmentStore { long StockNumber; char Category; string ItemName;

C# 3.0 Practical Learning

80

decimal UnitPrice; } }

2. Save the file

Accessing Class Members
Private 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 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 are examples:
public class House { string PropertyNumber; public char PropertyType; byte Stories; public uint bedrooms; private decimal Value; }

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. To reduce confusion as to what member is public or private, you should always specify the access level of a member variable.
public class House { public string PropertyNumber; public char PropertyType; public byte Stories; public uint Bedrooms;

C# 3.0 Practical Learning

81

public decimal Value; }

After creating 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 member, use the period operator ".".

Internal Members
We have seen that the public keyword is used to let objects of the same program and objects of other programs access the public member. The private keyword is used to let only members of a class access the (private) member of the class. If you want to create a member of a class so that only objects of the same program can access that member, you can mark it with the internal keyword. The differences between these keywords can be resumed as follows: If a class member is marked as
public private internal

Members of its class can Yes access this member Members of this program, including outside of the Yes class, can access this member Objects outside of this program can access this Yes member

Yes

Yes

No

Yes

No

No

Initializing an Object
Introduction
After declaring an instance of a class, you can access each of its members and assign it the desired value. Here is an example:
using System; public class House {

C# 3.0 Practical Learning

82

}

internal internal internal internal

long PropertyNumber; string PropertyType; uint Bedrooms; double Value;

public class Exercise { static void Main() { var Property = new House(); Property.PropertyNumber = 283795; Property.PropertyType = "Single Family"; Property.Bedrooms = 4; Property.Value = 652880;

} }

Once a member variable has been initialized, you can use the period operator to access it and retrieve its value:
using System; public class { internal internal internal internal } House long PropertyNumber; string PropertyType; uint Bedrooms; double Value;

public class Exercise { static void Main() { var Property = new House(); Property.PropertyNumber = 283795; Property.PropertyType = "Single Family"; Property.Bedrooms = 4; Property.Value = 652880; Console.WriteLine("=//= Altair Realty =//="); Console.WriteLine("Properties Inventory"); ; Console.Write("Property #: "); Console.WriteLine(Property.PropertyNumber); Console.Write("Property Type: "); Console.WriteLine(Property.PropertyType); Console.Write("Bedrooms: "); Console.WriteLine(Property.Bedrooms); Console.Write("Market Value: "); Console.WriteLine(Property.Value); } }

This would produce:
=//= Altair Realty =//= Properties Inventory

C# 3.0 Practical Learning

83

Property #: 283795 Property Type: Single Family Bedrooms: 4 Market Value: 652880 Press any key to continue . . .

Practical Learning: Using a Class' Fields
1. To make public the members of the DepartmentStore class, type the public keyword to their left:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore1 { class DepartmentStore { public long StockNumber; public char Category; public string ItemName; public double UnitPrice; } }

2. To access the Program.cs file, click its tab above the Code Editor 3. Change
using using using using Main()

as

follows:

System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore1 { class Program { static void Main(string[] args) { DepartmentStore dptStore = new DepartmentStore(); dptStore.StockNumber = 437876; dptStore.Category = 'W'; dptStore.ItemName = "Scoop Neck Dress"; dptStore.UnitPrice = 148.00D; Console.WriteLine("Department Store"); Console.Write("Stock #: "); Console.WriteLine(dptStore.StockNumber); Console.Write("Category: "); Console.WriteLine(dptStore.Category); Console.Write("Name: "); Console.WriteLine(dptStore.ItemName); Console.Write("Unit Price: ");

C# 3.0 Practical Learning

84

} } }

Console.WriteLine(dptStore.UnitPrice); Console.WriteLine();

4. Execute the application. This would produce:
Department Store Stock #: 437876 Category: W Name: Scoop Neck Dress Unit Price: 148.00 Press any key to continue . . .

5. Close the DOS window

Using an Anonymous Type
We saw that, to use a class, you could first declare a variable for it and initialize it. Fortunately, you don't have to use a class to initialize an object. You can declare a variable that resembles an instance of a class and initialize it as you see fit. This is referred to as an anonymous type. To use it, declare the variable using the var keyword and use the new operator to allocate memory for it. Instead of using the name of a class, type an opening and a closing curly brackets after the new operator. In the curly brackets, state a name for each member as if it were the member of the class and initialize each member variable with the desired value. After the closing curly bracket, end the declaration with a semi-colon. Here is an example:
using System; public class Exercise { static void Main() { var BookInformation = new { Title = "Calculus 6e Edition", Pages = 1074, Cover = "Hard Back" } } };

After initializing the anonymous type, you can access each one of its members using the name of the variable followed by the period operator, and followed by the member variable. Here is an example:
using System; public class Exercise { static void Main()

C# 3.0 Practical Learning

85

{ var BookInformation = new { Title = "Calculus 6e Edition", Pages = 1074, Cover = "Hard Back" }; Console.WriteLine("=//= BookInformation =//="); Console.Write("Title: "); Console.WriteLine(BookInformation.Title); Console.Write("Nbr of Pages: "); Console.WriteLine(BookInformation.Pages); Console.Write("Type of Cover: "); Console.WriteLine(BookInformation.Cover); } }

This would produce:
=//= BookInformation =//= Title: Calculus 6e Edition Nbr of Pages: 1074 Type of Cover: Hard Back Press any key to continue . . .

Remember that spreading the declaration on many lines only makes it easy to read. Otherwise, you can as well include everything on the same line.
using System; public class Exercise { static void Main() { var Book = new { Title = "Calculus 6e Edition", Pages = 1074 }; Console.WriteLine("=//= BookInformation =//="); Console.Write("Title: "); Console.WriteLine(BookInformation.Title); Console.Write("Nbr of Pages: "); Console.WriteLine(BookInformation.Pages); } }

The Methods of a Class
Introduction
When you create a class, the fields are meant to describe it. For a class named House, such aspects as the number of bedrooms, the property type, or its value, are used to describe it:
public class House { public char PropertyType; public uint Bedrooms;

C# 3.0 Practical Learning

86

}

Besides the characteristics used to describe it, an object can also perform actions or assignments. An action performed by a class is called a method. A method is simply a section of code that takes care of a particular detail for the functionality of the class. To create a method, you specify its name, which follows the rules we defined for variables. The name of a method is followed by parentheses. 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 some cases, a method must produce a result. If it doesn't, 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. If the method doesn't produce a result, type void to its left. The assignment that a method carries is included between an opening curly bracket "{" and a closing curly bracket "}". Here is an example:
public class House { public char PropertyType; public uint Bedrooms; void Display() { }

}

The most regularly used method of a C# program is called Main. Like a member variable:

If the method will be accessed only by members of the same class, you can mark it as private or not mark it with an access keyword If the method will be accessed by members of the class and other parts of the same program but not outside of the program, mark it with the internal keyword In the method can be accessed by the members of the same class, other parts of the same program, and other parts of other programs, mark it as
public

After creating a method, in its body delimited by its curly brackets, you can define the desired behavior. For example, you can write the member variables in the parentheses of Console.Write() or Console.WriteLine(). Here are examples:
public class House { public char PropertyType; public uint Bedrooms; internal void Display() { Console.WriteLine("=//= Altair Realty =//="); Console.WriteLine("Properties Inventory"); ; Console.Write("Property Type: "); Console.WriteLine(PropertyType);

C# 3.0 Practical Learning

87

} }

Console.Write("Bedrooms: Console.WriteLine(Bedrooms);

");

In the same way, you can create as many methods as you want in a class. To assist you with managing the methods of a class, the Code Editor is equipped with two combo boxes.

The left combo box, called Types, displays the classes that are part of the project. The right combo box, named Members, displays the members of the class that is selected in the Types combo box:

If you select an item from the Members combo box, the caret would be displayed on its declaration in the file.

The Solution Explorer
C# 3.0 Practical Learning
88

The Solution Explorer is a window that displays the file names and other items used in your project. The items of this window display in a tree. To expand a node, you can click its + button. To collapse it, click its - button. To explore an item, you can double-click it. The result depends on the item you doubleclicked. The Solution Explorer can be used to create and add a new class or a new item to the current project. It can also be used to add a another project to the current project. To perform any of these operations, you can right-click a folder node such as the name of the project and position the mouse on Add to select the desired operation:

Remember that you can also perform any of these operations from the Project category of the main menu. Besides adding new items to the project, you can also use the Solution Explorer to build the project or change its properties. If you add one or more other project(s) to the current one, one of the project must be set as the default. That project would be the first to come up when the user executes the application. By default, the first project created is set as the default. If you have more than one project, to set the default, right-click the name of the desired project in Solution Explorer and click Set As StartUp Project. The Solution Explorer also allows you to rename or delete some of the items that belong to your project.

Practical Learning: Creating the Methods of a Class
1. Access the DepartmentStore.cs file 2. To add some methods to the DepartmentStore class, change it as follows: C# 3.0 Practical Learning
89

using using using using

System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore1 { class DepartmentStore { public long StockNumber; public char Category; public string ItemName; public double UnitPrice; public void CreateItem() { StockNumber = 792475; Category = 'M'; ItemName = "Lightweight Jacket"; UnitPrice = 185.00D; } public void ShowItem() { Console.WriteLine("Department Store"); Console.Write("Stock #: "); Console.WriteLine(StockNumber); Console.Write("Category: "); Console.WriteLine(Category); Console.Write("Name: "); Console.WriteLine(ItemName); Console.Write("Unit Price: "); Console.WriteLine(UnitPrice); Console.WriteLine(); } } }

3. Access
using using using using

the

Program.cs

file

and

change

Main()

as

follows:

System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore1 { class Program { static void Main(string[] args) { DepartmentStore dptStore = new DepartmentStore(); dptStore.CreateItem(); dptStore.ShowItem(); } } }

C# 3.0 Practical Learning

90

4. Execute the application. This would produce:
Department Store Stock #: 792475 Category: M Name: Lightweight R4 Jacket Unit Price: $185.00 Press any key to continue . . .

5. Close the DOS window

Accessing a Method
After creating a method, you can access it outside of its class. You do this following the same rules used to access a field, using the period operator. Unlike a field, the name of a class must be followed by parentheses. Here is an example:
using System; public class House { public char PropertyType; public uint Bedrooms; internal void Display() { Console.WriteLine("=//= Altair Realty =//="); Console.WriteLine("Properties Inventory"); ; Console.Write("Property Type: "); Console.WriteLine(PropertyType); Console.Write("Bedrooms: "); Console.WriteLine(Bedrooms); } } public class Program { static void Main() { var Property= new House(); Property.PropertyType = 'S'; Property.Bedrooms = 4; Property.Display(); } }

This would produce:
=//= Altair Realty =//= Properties Inventory Property Type: S Bedrooms: 4 Press any key to continue . . .

C# 3.0 Practical Learning

91

The Static Members of a Class
Static Fields
Imagine you create a class called Book. To access it in the Main() method, 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 necessary:
using System; public class Book { public string public string public short public int public char }

Title; Author; YearPublished; NumberOfPages; CoverType;

public class Exercise { static void Main() { var written = new Book(); var 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 Title; public string Author; public short YearPublished; public int NumberOfPages; public char CoverType; } public class Exercise { static void Main() { var First = new Book(); First.Title = "Psychology and Human Evolution"; First.Author = "Jeannot Lamm"; First.YearPublished = 1996; First.NumberOfPages = 872; First.CoverType = 'H';

C# 3.0 Practical Learning

92

Console.WriteLine("Book Characteristics"); Console.Write("Title: "); Console.WriteLine(First.Title); Console.Write("Author: "); Console.WriteLine(First.Author); Console.Write("Year: "); Console.WriteLine(First.YearPublished); Console.Write("Pages: "); Console.WriteLine(First.NumberOfPages); Console.Write("Cover: "); Console.WriteLine(First.CoverType); var 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.Write("Title: "); Console.WriteLine(Second.Title); Console.Write("Author: "); Console.WriteLine(Second.Author); Console.Write("Year: "); Console.WriteLine(Second.YearPublished); Console.Write("Pages: "); Console.WriteLine(Second.NumberOfPages); Console.Write("Cover: "); Console.WriteLine(Second.CoverType); Console.WriteLine(); } }

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 93 C# 3.0 Practical Learning

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 specify its class. Here is an example:
using System; public class Book { public static string Title; public static string Author; public short YearPublished; public int Pages; public char CoverType; } public class Exercise { static void Main() { var First = new Book(); Book.Title = "Psychology and Human Evolution"; Book.Author = "Jeannot Lamm"; First.YearPublished = 1996; First.Pages = 872; First.CoverType = 'H'; Console.WriteLine("Book Characteristics"); Console.Write("Title: "); Console.WriteLine(Book.Title); Console.Write("Author: "); Console.WriteLine(Book.Author); Console.Write("Year: "); Console.WriteLine(First.YearPublished); Console.Write("Pages: "); Console.WriteLine(First.Pages); Console.Write("Cover: "); Console.WriteLine(First.CoverType); var Second = new Book(); Book.Title = "C# First Step"; Book.Author = "Alexandra Nyango"; Second.YearPublished = 2004; Second.Pages = 604; Second.CoverType = 'P'; Console.WriteLine("Book Characteristics"); Console.Write("Title: "); Console.WriteLine(Book.Title); Console.Write("Author: "); Console.WriteLine(Book.Author); Console.Write("Year: "); Console.WriteLine(Second.YearPublished); Console.Write("Pages: "); Console.WriteLine(Second.Pages); Console.Write("Cover: "); Console.WriteLine(Second.CoverType); Console.WriteLine();

C# 3.0 Practical Learning

94

} }

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 Exercise { static void Main() { Book.Title = "Psychology and Human Evolution"; Book.Author = "Jeannot Lamm"; Console.WriteLine("Book Characteristics"); Console.WriteLine("Title: "); Console.WriteLine(Book.Title); Console.WriteLine("Author: "); Console.WriteLine(Book.Author); Book.Title = "C# First Step"; Book.Author = "Alexandra Miles"; Console.WriteLine("Book Characteristics"); Console.WriteLine("Title: "); Console.WriteLine(Book.Title); Console.WriteLine("Author: "); Console.WriteLine(Book.Author); Console.ReadLine(); } }

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 Exercise { static double Length; static double Width; static void Main() { Console.WriteLine("Rectangles Characteristics");

C# 3.0 Practical Learning

95

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(); } }

Static Methods
Like a member variable, a method of a class can be defined as static. Consequently, 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 static public { Title Author Pages Price }

string string int double

Title; Author; Pages; Price;

void CreateBook() = = = = "Psychology and Human Evolution"; "Jeannot Lamm"; 472; 24.95;

static public void ShowBook() { Console.WriteLine("Book Characteristics"); Console.Write("Title: "); Console.WriteLine(Book.Title); Console.Write("Author: "); Console.WriteLine(Book.Author); Console.Write("Pages: "); Console.WriteLine(Pages); Console.Write("Price: ");

C# 3.0 Practical Learning

96

Console.WriteLine(Price); } }

public class Exercise { 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.

Static Classes
A static class: 1. Is a class whose members must be accessed without an instance of the class. In other words, the members of a static class must be accessed directly from (using the name of) the class, using the period operator 2. Is a class whose members must be created as static. In other words, you cannot add a non-static member to a static class: all members, except for constants, must be static To create a static class, precede the class keyword with the static keyword. Based on the above two rules, here is an example:
using System; namespace Staticity { public static class Square { public static double Side; public static double Perimeter() { return Side * 4; } public static double Area() { return Side * Side; }

}

public class Exercise

C# 3.0 Practical Learning

97

{ static void Main(string[] args) { Square.Side = 36.84; Console.WriteLine("Square Characteristics"); Console.Write("Side: "); Console.WriteLine(Square.Side); Console.Write("Perimeter: "); Console.WriteLine(Square.Perimeter()); Console.Write("Area: "); Console.WriteLine(Square.Area());

} } }

This would produce:
Square Characteristics Side: 36.84 Perimeter: 147.36 Area: 1357.1856 Press any key to continue . . .

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 constant value.

this Instance
If a class contains fields and methods, the (non-static) field members are automatically available to the method(s) of the class, even fields that are private. When accessing a field or a method from another method of the class, to indicate that the member you are accessing belongs to the same class, you can precede it with the this member and the period operator. Here are examples:
public class House { internal char PropertyType; internal uint Bedrooms; internal void Display() { Console.WriteLine("=//= Altair Realty =//="); Console.WriteLine("Properties Inventory"); ; Console.Write("Property Type: "); Console.WriteLine(this.PropertyType); Console.Write("Bedrooms: ");

C# 3.0 Practical Learning

98

Console.WriteLine(this.Bedrooms); } }

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. There are rules you must observe 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:

public class Exercise { static void Main() { House property = new House(); property.PropertyType = 'S'; property.Bedrooms = 4; this.property.Display(); }

} this cannot be used in a static method

Practical Learning: Using this
1. Access the DepartmentStore.cs file and, to use this, change the class as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore1 { class DepartmentStore { public long StockNumber; public char Category; public string ItemName; public double UnitPrice; public void CreateItem() { this.StockNumber = 792475; this.Category = 'M'; this.ItemName = "Lightweight Jacket"; this.UnitPrice = 185.00D; }

C# 3.0 Practical Learning

99

public void ShowItem() { Console.WriteLine("Department Store"); Console.Write("Stock #: "); Console.WriteLine(this.StockNumber); Console.Write("Category: "); Console.WriteLine(this.Category); Console.Write("Name: "); Console.WriteLine(this.ItemName); Console.Write("Unit Price: "); Console.WriteLine(this.UnitPrice); Console.WriteLine(); } } }

2. Execute the application to see the result 3. Close the DOS window

C# 3.0 Practical Learning

100

5 - C# AND CODE ORGANIZATION
Namespaces
Introduction
A namespace is a section of code that is identified with 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 Business { }

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:
namespace Business { class House { } }

Practical Learning: Creating a Namespacep>
1. Start Microsoft Visual C# 2005 and create a new Console Application named RealEstate1 2. To create a new class, in the Class View, right-click the name of the project, position the mouse on Add and click Class... 3. Change the name to House and press Enter 4. Change the class as follows:
using System;

C# 3.0 Practical Learning

101

using System.Collections.Generic; using System.Linq; using System.Text; namespace RealEstate1 { public class House { public string PropertyNumber; public char PropertyType; public uint Stories; public uint Bedrooms; public float Bathrooms; public double Value; } }

5. Save the file

Accessing Members of a Namespace
After creating the necessary members of 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:
using System; namespace Business { public class House { public string PropertyNumber; public decimal Price; } } public class Exercise { static void Main() { Business.House property = new Business.House(); property.PropertyNumber = "D294FF"; property.Price = 425880; Console.WriteLine("=//= Altair Realty =//="); Console.WriteLine("Properties Inventory"); Console.Write("Property #: "); Console.WriteLine(property.PropertyNumber); Console.Write("Market Value: "); Console.WriteLine(property.Price); Console.WriteLine(); } }

This would produce:
=//= Altair Realty =//=

C# 3.0 Practical Learning

102

Properties Inventory Property #: D294FF Market Value: 425880 Press any key to continue . . .

Namespace Nesting
You can create one namespace inside of another namespace. Creating a namespace inside of another 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 example:
namespace Business { public class House { public string PropertyNumber; public decimal Price; } namespace Dealer { }

}

In the example above, the Dealer namespace is nested inside of the Business namespace. After creating the desired namespaces, nested or not, you can create the necessary class(es) 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:
using System; namespace Business { public class House { public string PropertyNumber; public decimal Price; } namespace Dealer { public class Car { public decimal Price; } }

}

public class Exercise { static void Main() { Business.House property = new Business.House();

C# 3.0 Practical Learning

103

property.PropertyNumber = "D294FF"; property.Price = 425880; Console.WriteLine("=//= Altair Realty =//="); Console.WriteLine("Properties Inventory"); Console.Write("Property #: "); Console.WriteLine(property.PropertyNumber); Console.Write("Market Value: "); Console.WriteLine(property.Price); Console.WriteLine(); Business.Dealer.Car vehicle = new Business.Dealer.Car(); vehicle.Price = 38425.50M; Console.Write("Car Value: "); Console.WriteLine(vehicle.Price); } }

This would produce:
=//= Altair Realty =//= Properties Inventory Property #: D294FF Market Value: 425880 Car Value: 38425.50 Press any key to continue . . .

In the same way, you can nest as many namespaces inside of other namespaces as you judge necessary.

The System Namespace
Introduction
To make programming in C# a little easier, many classes ship with it and they are created in various namespaces of the .NET Framework. Each namespace in C# is used to provide a specific 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 static 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 doublequotes. Here is an example:
public class Exercise { static void Main() { System.Console.Write("The Wonderful World of C# Programming");

C# 3.0 Practical Learning

104

} }

Besides the Write() method, the Console class also provides another static method named 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 to the next line. We will see various examples of this behavior throughout our lessons.

Using a Namespace
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

Access the Program.cs file and notice that it has a using declaration

.NET Support of Data Types
Introduction
In C# (unlike many other languages such as C/C++, Pascal, etc), all of the data types we have used so far are in fact complete classes. This means that they are equipped with methods. These classes are defined in the System namespace. The classes of these data types are defined as:
C# Data Type Equivalent .NET Class C# Data Type Equivalent . NET Class

bool byte short int long

Boolean Byte Int16 Int32 Int64

char sbyte ushort uint ulong

Char SByte UInt16 UInt32 UInt64
105

C# 3.0 Practical Learning

float decimal

Single Decimal

double

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; } }

Because the regular names of data types we introduced in the previous lessons are more known and familiar, we will mostly use them. Because the data types are defined as classes, they are equipped with methods. One of the methods that each one of them has is called ToString. As its name implies, it is used to convert a value to a string.

C# Language Accessories
Command Line Options
In Lesson 1, we saw that, to see the result of an application, you must execute it. To make this possible,, Microsoft Visual C# ships with an internal program called a compiler. A compiler is a computer program made of internal other sub-programs. One of the sub-programs, 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, C# 3.0 Practical Learning
106

you will know how to fix the programs or troubleshoot these problems. In this ebook, 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, 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 subprograms (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 "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 Microsoft .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. The csc compiler is freely available if you download the .NET Framework from the Microsoft web site. In this book, we will create our program using Microsoft Visual C# but if you didn't have it, you would still be able to create and execute applications. To do this, at the Command Prompt, you would type csc, followed by the name of the file that contains the code with its extension. An example would be:
csc Filename.cs

When you do this, an executable with the same name as the file is created. If you want, you can ask the compiler to produce an executable using the name of your choice. To do this, you would compile the project using the following formula:
csc /out:NameOfExecutate.exe Filename.cs

The NameOfExecutate factor in our formula represents the name you want the executable to have. If the name you want is in one word, you can just type it. If you want a name made of various words, you can include those words in double-quotes The FileName factor is one we are familiar with.

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. C/C++ uses pointers to refer to the area in memory where a value is located. C# highly C# 3.0 Practical Learning
107

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 when 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. Here is an example:
using System; class Exercise { unsafe static void Main() { int Length = 224; int *Len = &Length; Console.Write("Length "); Console.WriteLine(Length); Console.Write("Length "); Console.WriteLine(*Len); Console.WriteLine(); Length = 804; Console.Write("Length "); Console.WriteLine(Length); Console.Write("Length "); Console.WriteLine(*Len); } }

To compile the application, you must indicate that you are using unsafe code. To do that, use the /unsafe modifier. Here is an example:
csc /unsafe Exercise.cs

To apply this option in Microsoft Visual C#, on the main menu, you can click Project -> Project Properties... In the Build section, click the Allow Unsafe Code check box:

C# 3.0 Practical Learning

108

Code Editor

Region Delimiter

Microsoft Visual C# provides various techniques to assist you with code writing and management. The characteristics include color-coded words, intuitive indentation, delimitation of sections of code, etc. Consider the following contents of the Code Editor based on what we have reviewed so far:

C# 3.0 Practical Learning

109

Notice that there are - buttons on the left side of some lines of code. These allow you to collapse a section of code if you think you don't need to see it. To do this, you can click the - button. If you click that - button, it changes into a + button. Here is an example:

C# 3.0 Practical Learning

110

The + button allows you to expand a hidden code section. This behavior of creating + and - buttons is part of the Code Editor of Microsoft Visual Studio (yes, many other programming environments use that behavior also). To create these sections, the Code Editor follows some rules. For example, it looks for the start and end of such items as directives, namespaces, classes, methods, etc. Besides, or instead of, the sections of code created by the Code Editor, if you want, you can create your own sections. To do this, start the section with
#region Whatever

and end it with
#endregion Whatever

When and where you start, the #region expression is required. On the right side of this expression, you can type anything you want on the line. To end the section, type #endregion, followed by anything you want. Consider the following example:
using System; class House { void Create() { } } #region These are classes used for Student Registration

C# 3.0 Practical Learning

111

class Car { void Build() { } } class Student { void Register() { } } #endregion We can just stop it here class Program { static void Main() { } }

You don't have to type anything on the right side of #endregion. After creating the region, the Code Editor would display a - button to the left side of #region with a line from there to the left of #endregion:

This then allows you to expand and collapse that section at will: C# 3.0 Practical Learning
112

We mentioned that you didn't have to type anything on the right side of #endregion and you could leave it empty. In our example, notice that there is a rectangle with gray lines around the string that follows #region. This rectangle doesn't cover the string that follows #endregion. This means that if you don't type anything on the right side of #endregion, that section on the right side the #region line would not show.

C# 3.0 Practical Learning

113

6 - DATA READING AND FORMATTING
Data Reading
Introduction
In previous lessons, we saw that the Console class allows using the Write() and the WriteLine() methods 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 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

Start Microsoft Visual C# and create a Console Application named
GeorgetownCleaningServices4

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 C# 3.0 Practical Learning
114

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:
using System; public class Exercise { public static void Main() { 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 using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GeorgetownCleaningServices4 { class Program { static void Main(string[] args) { 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"); } } }

C# 3.0 Practical Learning

115

2. Execute the program. This would produce:
-/- Georgetown Cleaning Services -/Enter Customer Name: James Watson Enter Customer Phone: (410) 493-2005 ==================================== -/- Georgetown Cleaning Services -/==================================== Customer: James Watson Home Phone: (410) 493-2005 ====================================

3. Close the DOS window

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; public class Exercise { public 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; public class Exercise { public 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 Parse. This has the same effect. Here is an example: C# 3.0 Practical Learning
116

using System; public class Exercise { public static int Main() { int Number; Number = int.Parse(Console.ReadLine()); return 0; } }

Practical Learning: Reading Numeric Values
1. To retrieve various numbers from the user, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GeorgetownCleaningServices4 { class Program { static void Main(string[] args) { // Price of items const double PriceOneShirt = 0.95; const double PriceAPairOfPants = 2.95; const double PriceOneDress = 4.55; const double TaxRate = 0.0575; // 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 double SubTotalShirts, SubTotalPants, SubTotalDresses; // Values used to process an order double TotalOrder, TaxAmount, SalesTotal; double 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(); // 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: "); 117

C# 3.0 Practical Learning

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 = double.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 "); Console.Write(NumberOfPants); Console.Write(" "); Console.Write(PriceAPairOfPants); Console.Write(" "); Console.WriteLine(SubTotalPants); Console.Write("Dresses "); Console.Write(NumberOfDresses); Console.Write(" "); Console.Write(PriceOneDress);

C# 3.0 Practical Learning

118

} } }

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. Execute the program and test it. Here is an example:
-/- 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 -----------------------------------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 ====================================

3. Close the DOS window

Requesting Dates and Times
C# 3.0 Practical Learning
119

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 using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GeorgetownCleaningServices4 { class OrderProcessing { static void Main() { // Price of items const double PriceOneShirt const double PriceAPairOfPants const double PriceOneDress const double TaxRate

= = = =

0.95; 2.95; 4.55; 0.0575;

// 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

C# 3.0 Practical Learning

120

double SubTotalShirts, SubTotalPants, SubTotalDresses; // Values used to process an order double TotalOrder, TaxAmount, SalesTotal; double 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: "); 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 = double.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);

C# 3.0 Practical Learning

121

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: "); Console.WriteLine(AmountTended); Console.Write("Difference: "); Console.WriteLine(Difference); Console.WriteLine("===================================="); } } }

2. Execute the program and test it. Here is an example:
-/- 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

C# 3.0 Practical Learning

122

==================================== -/- 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 ====================================

3. Return to Notepad

Formatting Data Display
Introduction
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: C# 3.0 Practical Learning
123

using System; public class Exercise { public static void Main() { var FullName = "Anselme Bogos"; var Age = 15; var 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 create a meaningful sentence.

Practical Learning: Displaying Data With Placeholders
1. To use curly brackets to display data, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GeorgetownCleaningServices4 { class OrderProcessing { static void Main() { // Price of items const double PriceOneShirt const double PriceAPairOfPants const double PriceOneDress const double TaxRate

= = = =

0.95; 2.95; 4.55; 0.0575;

// 5.75%

// Basic information about an order string CustomerName, HomePhone; DateTime OrderDate; // Unsigned numbers to represent cleaning items

C# 3.0 Practical Learning

124

uint NumberOfShirts, NumberOfPants, NumberOfDresses; // Each of these sub totals will be used for cleaning items double SubTotalShirts, SubTotalPants, SubTotalDresses; // Values used to process an order double TotalOrder, TaxAmount, SalesTotal; double 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()); // 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 = double.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("Date & Time: {0}", OrderDate);

C# 3.0 Practical Learning

125

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, SubTotalDresses); 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. Execute the program and test it 3. Close the DOS window

Conversion To String
We mentioned earlier that everything the user types using the keyboard is primarily a string 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 convert a value of a primitive data type to a string, type the name of the variable, followed by a period, followed by ToString(). Here is an example:
using System; public class Exercise { public static void Main() { var FullName = "Anselme Bogos"; var Age = 15; var HSalary = 22.74; Console.WriteLine("Full Name: {0}", FullName); Console.WriteLine("Age: {0}", Age.ToString()); Console.WriteLine("Distance: {0}", HSalary.ToString()); Console.WriteLine(); }

C# 3.0 Practical Learning

126

}

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 using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GeorgetownCleaningServices4 { class OrderProcessing { static void Main() { // Price of items const double PriceOneShirt const double PriceAPairOfPants const double PriceOneDress const double TaxRate . . . No Change

= = = =

0.95; 2.95; 4.55; 0.0575;

// 5.75%

} } }

Console.WriteLine("------------------------------------"); Console.WriteLine("Shirts {0} {1} {2}", NumberOfShirts.ToString(), PriceOneShirt, SubTotalShirts.ToString()); Console.WriteLine("Pants {0} {1} {2}", NumberOfPants, PriceAPairOfPants, SubTotalPants); Console.WriteLine("Dresses {0} {1} {2}", NumberOfDresses, PriceOneDress, SubTotalDresses); Console.WriteLine("------------------------------------"); Console.WriteLine("Total Order: {0}", TotalOrder); Console.WriteLine("Tax Rate: {0}%", TaxRate * 100); Console.WriteLine("Tax Amount: {0}", TaxAmount.ToString()); Console.WriteLine("Net Price: {0}", SalesTotal); Console.WriteLine("------------------------------------"); Console.WriteLine("Amount Tended: {0}", AmountTended); Console.WriteLine("Difference: {0}", Difference); Console.WriteLine("====================================");

2. Execute the program and test it 3. Close the DOS window

Number Formatting
C# 3.0 Practical Learning
127

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 letters 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 Used For

c d e f g n r x p Here are examples:
using System;

C D E F G N R X P

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

public class Exercise { public static void Main() { var Distance = 248.38782;

C# 3.0 Practical Learning

128

var var var var var

Age = 15; NewColor = 3478; HSalary = 22.74; HoursWorked = 35.5018473; 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 using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GeorgetownCleaningServices4 { class OrderProcessing { static void Main() { // Price of items const double PriceOneShirt const double PriceAPairOfPants const double PriceOneDress const double TaxRate

= = = =

0.95; 2.95; 4.55; 0.0575;

// 5.75%

// Basic information about an order string CustomerName, HomePhone; DateTime OrderDate; // Unsigned numbers to represent cleaning items

C# 3.0 Practical Learning

129

uint NumberOfShirts, NumberOfPants, NumberOfDresses; // Each of these sub totals will be used for cleaning items double SubTotalShirts, SubTotalPants, SubTotalDresses; // Values used to process an order double TotalOrder, TaxAmount, SalesTotal; double 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()); // 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 = double.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("Date & Time: {0}", OrderDate); Console.WriteLine("------------------------------------");

C# 3.0 Practical Learning

130

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. 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 -----------------------------------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

C# 3.0 Practical Learning

131

====================================

3. Close the DOS window

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; public class Exercise { public static void Main() { var FullName = "Anselme Bogos"; var Age = 15; var 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 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 C# 3.0 Practical Learning
132

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 using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GeorgetownCleaningServices4 { class OrderProcessing { static void Main() { // Price of items const double PriceOneShirt const double PriceAPairOfPants const double PriceOneDress const double TaxRate

= = = =

0.95; 2.95; 4.55; 0.0575;

// 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 double SubTotalShirts, SubTotalPants, SubTotalDresses; // Values used to process an order double TotalOrder, TaxAmount, SalesTotal; double 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()); Console.Write("Number of Pants: "); NumberOfPants = uint.Parse(Console.ReadLine()); Console.Write("Number of Dresses: "); NumberOfDresses = uint.Parse(Console.ReadLine()); // Perform the necessary calculations

C# 3.0 Practical Learning

133

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.WriteLine("\nThe Total order is: {0:C}", SalesTotal); // and request money for the order Console.Write("Amount Tended? "); AmountTended = double.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("------------------------------------"); 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"));

C# 3.0 Practical Learning

134

Console.WriteLine("Difference: {0}", Difference.ToString("C")); Console.WriteLine("===================================="); } } }

2. Execute 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. Close the DOS window

C# 3.0 Practical Learning

135

DETAILS ON THE METHODS OF A CLASS
Methods and Local Variables
Introduction
In the body of a method, you can declare one or more variables that would be used only by the method. A variable declared in the body of a method is referred to as a local variable. The variable 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. Start Microsoft Visual C# and create a Console Application named
Geometry1

2. To create a new class, on the main menu, click Project -> Add Class... 3. Set the Name to Cylinder and click Add 4. To declare and use local variables of a method, change the file as follows:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Geometry1 { public class Cylinder { public void Process() { double Radius, Height; double BaseArea, LateralArea, TotalArea; double Volume; Console.WriteLine("Enter the dimensions of the cylinder");

C# 3.0 Practical Learning

136

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 + Radius); Volume = Math.PI * Radius * 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); } } }

5. Access the Program.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry1 { public class Program { static void Main() { Cylinder cyl = new Cylinder(); cyl.Process(); Console.WriteLine(); } } }

6. Execute the application to test it. 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

C# 3.0 Practical Learning

137

7. Close the DOS window

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 { 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() { } }

C# 3.0 Practical Learning

138

When a method returns a value, the compiler considers such a method as were a regular value. This means that you can use the Console.Write() or Console.WriteLine() method to display its value. To do this, simply type name of the method and its parentheses in the Console.Write() of Console.WriteLine() methods' parentheses. Here is an example:
using System; class Exercise { static double Operation() { return 24.55; } static void Main() { Console.WriteLine(Operation()); } }

if it the the the

In the same way, a method that returns a value can be assigned to a variable of the same type.

Practical Learning: Returning a Value From a Method
1. Access the Cylinder.cs file 2. To create methods that return values, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry1 { class Cylinder { public double GetRadius() { double rad; Console.Write("Radius: "); rad = double.Parse(Console.ReadLine()); return rad; } public double GetHeight() { double h; Console.Write("Height: "); h = double.Parse(Console.ReadLine()); return h;

C# 3.0 Practical Learning

139

} public void Process() { 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; 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);

} } }

3. Execute the application. Here is an example:
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

4. Close the DOS window

The Main Method of an Application
So far, we have used the Main() method as it is defined by default when you create an application using using New Project dialog box. This default implementation of the Main() method is of type void. Another way to implement the Main() method is to make it return an integer. The rule is the same as for any method of type int. The Main() method can return any type of integer as long as it is a valid integer. Here is an example:
using System; class Exercise {

C# 3.0 Practical Learning

140

static char HaveCharacter() { return 'G'; } static int Main() { Console.Write("Character: "); Console.WriteLine(HaveCharacter()); return 244006; } }

This would produce:
Character: G Press any key to continue . . .

Methods' Arguments
Introduction
A method performs an assignment that completes the operations of a class. The methods we used in the previous sections relied on local 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 value(s). When a method needs a value to complete its assignment, such a value is called an argument. 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. Suppose you want to define a method that displays the side length of a square. Since you would have to supply the length, you can define such a method as follows:
using System; public class Exercise { static void DisplaySide(double Length) { }

C# 3.0 Practical Learning

141

static int Main() { return 0; } }

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 Exercise { static void DisplaySide(double Length) { Console.Write("Length: "); Console.WriteLine(Length); } static int Main() { return 0; }

}

When calling a method that takes an argument, you must supply a value for the argument; otherwise you would receive an error. Also, you should/must supply the right value; otherwise, the method may not work as expected and it may produce an unreliable result. Here is an example:
using System; public class Exercise { static void DisplaySide(double Length) { Console.Write("Length: "); Console.WriteLine(Length); } static int Main() { DisplaySide(35.55); } } return 0;

As mentioned already, a method that takes an argument can also declare its own local variable(s). 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

C# 3.0 Practical Learning

142

1. Access the Cylinder.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry1 { public class Cylinder { public double GetRadius() { double rad; Console.Write("Radius: "); rad = double.Parse(Console.ReadLine()); return rad; } public double GetHeight() { double h; Console.Write("Height: "); h = double.Parse(Console.ReadLine()); return h; } public double CalculateBaseArea(double rad) { return rad * rad * Math.PI; } public double CalculateLateralArea(double rad, double hgt) { return 2 * Math.PI * rad * hgt; } public double CalculateTotalArea(double rad, double hgt) { return 2 * Math.PI * rad * (hgt + rad); } public double CalculateVolume(double rad, double hgt) { return Math.PI * rad * rad * hgt; } public void Process() { double Radius; double Height; double BaseArea; double LateralArea; double TotalArea; double Volume;

C# 3.0 Practical Learning

143

Console.WriteLine("Enter the dimensions of the cylinder"); Radius = GetRadius(); Height = GetHeight(); BaseArea = CalculateBaseArea(Radius); LateralArea = CalculateLateralArea(Radius, Height); TotalArea = CalculateTotalArea(Radius, Height); Volume = 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); } } }

2. Execute the program:
Enter the dimensions of the cylinder Radius: 35.96 Height: 30.28 Cylinder Radius: Height: Base: Lateral: Total: Volume: Characteristics 35.96 30.28 4062.46 6841.56 14966.49 123011.33

3. Close the DOS window

Techniques of Passing Arguments
Passing an Argument by Value
When calling a methods that takes one or more arguments, we made sure we provided the necessary value. This is because an argument is always required and the calling method must provide a valid value when calling such a method.

Passing an Argument by Reference
Consider the following program:
using System; public class Payroll { static void Earnings(double ThisWeek, double Salary)

C# 3.0 Practical Learning

144

{ 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 int Main() { double Hours, Rate; Rate = 15.58; Hours = 26.00; Console.WriteLine("In the Main() method,"); Console.Write("\nWeekly Hours = "); Console.Write(Hours); Console.Write("\nSalary = "); Console.WriteLine(Rate); Console.Write("Weekly Salary = "); Console.WriteLine(Hours * Rate); Console.WriteLine("\nCalling the Earnings() method"); Earnings(Hours, Rate); Console.Write("\nAfter calling the Earnings() method, "); 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"); return 0;

} }

This would produce:
In the Main() method, Weekly Hours Salary Weekly Salary = 26 = 15.58 = 405.08

Calling the Earnings() method In the Earnings() function, Weekly Hours = 42.5 Salary = 15.58 Weekly Salary: = 662.15

C# 3.0 Practical Learning

145

After calling the Earnings() method, in the Main() function, Weekly Hours Salary Weekly Salary = 26 = 15.58 = 405.08

Press any key to continue

Notice that the weekly hours and salary values are the same before and after calling the Earnings() method. When you declare a variable in a program, the compiler reserves an amount of space for that variable. If you need to use that variable somewhere in your program, you call it and make use of its value. There are two major issues related to a variable: its value and its location in the memory. The location of a variable in memory is referred to as its address. If you supply the argument using its name, the compiler only makes a copy of the argument’s value and gives it to the calling method. Although the calling method receives the argument’s value and can use it in any way, it cannot (permanently) alter it. C# allows a calling method to modify the value of a passed argument if you find it necessary. If you want the calling method to modify the value of a supplied argument and return the modified value, you should pass the argument using its reference. To pass an argument as a reference, when defining and when calling the method, precede the argument's data type with the ref keyword. You can pass 0, one, or more arguments as reference in the program or pass all arguments as reference. The decision as to which argument(s) should be passed by value or by reference is based on whether or not you want the called method to modify the argument and permanently change its value. Another option consists of passing an argument using the out keyword. Here is an example:
using System; class Exercise { static void Initializer(out double n) { n = 128.44; } public static int Main() { double Number = 15.25; Console.WriteLine("Number = {0}", Number); return 0; } }

If you pass an argument with out, any modification made on the argument would be kept when the method ends. When calling a method that takes an out argument, precede the argument with the out keyword. Here is an example: C# 3.0 Practical Learning
146

using System; class Exercise { static void Initializer(out double n) { n = 128.44; } public static int Main() { double Number = 15.25; Console.WriteLine("Number = {0}", Number); Initializer(out Number); Console.WriteLine("Number = {0}", Number); return 0; } }

This would produce:
Number = 15.25 Number = 128.44

Practical Learning: Passing Arguments By Reference
1. To pass arguments by reference, change the Cylinder.cs file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry1 { class Cylinder { public void GetRadius(ref double rad) { Console.Write("Radius: "); rad = double.Parse(Console.ReadLine()); } public void GetHeight(out double h) { Console.Write("Height: "); h = double.Parse(Console.ReadLine()); } public double CalculateBaseArea(double rad) { return rad * rad * Math.PI; } public double CalculateLateralArea(double rad, double hgt) { return 2 * Math.PI * rad * hgt;

C# 3.0 Practical Learning

147

} public double CalculateTotalArea(double rad, double hgt) { return 2 * Math.PI * rad * (hgt + rad); } public double CalculateVolume(double rad, double hgt) { return Math.PI * rad * rad * hgt; } public void Process() { double Radius = 0.00; double Height = 0.00; double BaseArea; double LateralArea; double TotalArea; double Volume; Console.WriteLine("Enter the dimensions of the cylinder"); GetRadius(ref Radius); GetHeight(out Height); BaseArea = CalculateBaseArea(Radius); LateralArea = CalculateLateralArea(Radius, Height); TotalArea = CalculateTotalArea(Radius, Height); Volume = 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); } } }

2. Execute the application to test it. Here is an example:
Enter the dimensions of the cylinder Radius: 24.55 Height: 20.85 Cylinder Radius: Height: Base: Lateral: Total: Volume: Characteristics 24.55 20.85 1893.45 3216.16 7003.05 39478.34

3. Close the DOS window

Method Overloading
C# 3.0 Practical Learning
148

A typical program involves a great deal of names that represent variables and methods of various kinds. The compiler does not allow two variables to have the same name in the same method. Although two methods should have unique names in the same program, a class can have different methods with the same name if you follow some rules. The ability to have various methods with the same name in the same program is referred to as method overloading. To perform overloading, the methods must have different numbers or different type(s) of arguments. The moment of inertia is the ability of a beam to resist bending. It is calculated with regard to the cross section of the beam. Because it depends on the type of section of the beam, its calculation also depends on the type of section of the beam. In this exercise, we will review different formulas used to calculate the moment of inertia. Since this exercise is for demonstration purposes, you do not need to be a Science Engineering major to understand it.

Practical Learning: Overloading a Method
1. Create a new Console Application named
MomentOfInertia1

2. Change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

public class Exercise { // Rectangle static double MomentOfInertia(double b, double h) { return b * h * h * h / 3; } static int Main() { double Base, Height; Console.WriteLine("Enter the dimensions of the Rectangle"); Console.Write("Base: ");

C# 3.0 Practical Learning

149

Base = double.Parse(Console.ReadLine()); Console.Write("Height: "); Height = double.Parse(Console.ReadLine()); Console.WriteLine("\nMoment of inertia with " + "regard to the X axis: "); Console.WriteLine("I = {0}mm", MomentOfInertia(Base, Height)); Console.WriteLine(); return 0; } }

3. Execute the application. Here is an example of running the program:
Enter the dimensions of the Rectangle Base: 2.44 Height: 3.58 Moment of inertia with regard to the X axis: I = 37.3179390933333mm

4. Close the DOS window 5. A circle, and thus a semi-circle, requires only a radius. Since the other version of the MomentOfInertia() function requires two arguments, we can overload it by providing only one argument, the radius. To overload the above MomentOfInertia() method, type the following in the file:

using using using using

System; System.Collections.Generic; System.Linq; System.Text;

public class Exercise { // Rectangle static double MomentOfInertia(double b, double h) { return b * h * h * h / 3; } // Semi-Circle static double MomentOfInertia(double R) { const double PI = 3.14159; return R * R * R * R * PI/ 8; }

C# 3.0 Practical Learning

150

static int Main() { double Base, Height; double Radius; Console.WriteLine("Enter the dimensions of the Rectangle"); Console.Write("Base: "); Base = double.Parse(Console.ReadLine()); Console.Write("Height: "); Height = double.Parse(Console.ReadLine()); Console.WriteLine("\nMoment of inertia with regard to the X axis: "); Console.WriteLine("I = {0}mm", MomentOfInertia(Base, Height)); Console.Write("\nEnter the radius: "); Radius = double.Parse(Console.ReadLine()); Console.WriteLine("Moment of inertia of a semi-circle " + "with regard to the X axis: "); Console.WriteLine("I = {0}mm", MomentOfInertia(Radius)); Console.WriteLine(); return 0; } }

6. Execute the program. Here is an example:
Enter the dimensions of the Rectangle Base: 4.25 Height: 2.55 Moment of inertia with regard to the X axis: I = 23.49028125mm Enter the radius: 5.35 Moment of inertia of a semi-circle with regard to the X axis: I = 321.717471644992mm

7. Close the DOS window 8. Here are the formulas considered for a triangle:

9. As you can see, the rectangle and the triangle are using the same dimension types. This means that we can provide only the same kinds of arguments, the base and the height, to calculate the moment of inertia. C# 3.0 Practical Learning
151

This also means that the compiler will not allow us to write two methods that have the same name, the same number of arguments, and the same types of arguments because that would violate the rule of function overloading. 10. In order to overload the MomentOfInertia() function, we will add an argument that will never be used; this argument will serve only as a “witness” to set the difference between both versions of the function. This “witness” argument can be anything: an integer, a character, a string, a float, etc. For our example, we will make it a simple integer. To use the version applied to the triangle, we will provide this argument to overload the MomentOfInertia() function. When called with only two arguments, the rectangle version will apply. Change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

public class Exercise { // Rectangle static double MomentOfInertia(double b, double h) { return b * h * h * h / 3; } // Semi-Circle static double MomentOfInertia(double R) { const double PI = 3.14159; } return R * R * R * R * PI/ 8;

// Triangle static double MomentOfInertia(double b, double h, int i) { return b * h * h * h / 12; } static int Main() { double Base = 7.74, Height = 14.38, Radius = 12.42; Console.WriteLine( "Rectangle - Moment of inertia with regard to the X axis: "); Console.WriteLine("I = {0}mm", MomentOfInertia(Base, Height)); Console.WriteLine("\nSemi-Circle - Moment of inertia of a " + "semi-circle with regard to the X axis: "); Console.WriteLine("I = {0}mm", MomentOfInertia(Radius)); Console.WriteLine("\nEnter the dimensions of the triangle"); Console.Write("Base: "); Base = double.Parse(Console.ReadLine());

C# 3.0 Practical Learning

152

Console.Write("Height: "); Height = double.Parse(Console.ReadLine()); Console.WriteLine( "\nTriangle - Moment of inertia with regard to the X axis: "); Console.WriteLine("I = {0}mm", MomentOfInertia(Base, Height, 1)); Console.WriteLine(); return 0; } }

11.

Execute the program. Here is an example:

Rectangle - Moment of inertia with regard to the X axis: I = 7671.78395376mm Semi-Circle - Moment of inertia of a semi-circle with regard to the X axis: I = 9344.28126291881mm Enter the dimensions of the triangle Base: 5.52 Height: 3.84 Triangle - Moment of inertia with regard to the X axis: I = 26.04662784mm

12.

Close the DOS window

Class Construction and Destruction
Method Initializer
Imagine you are writing a program for a business that sells flowers:

Flower

Type Color

Daisies White

Lilies Mixed Vase

Roses Red Bouquet

Live Plants Green Basket

Orchids Pink Vase

Arrangement Vase

C# 3.0 Practical Learning

153

Price

37.15

29.95

85.95

60.95

55.95

Consider the following program:
using System; public class Flower { public int Type; public int Color; public char Arrangement; public double UnitPrice;

}

public class Exercise { static int Main() { var flr = new Flower(); Console.WriteLine("Flower Type: Console.WriteLine("Flower Color: Console.WriteLine("Arrangement: Console.WriteLine("Price: Console.WriteLine(""); return 0; {0}", flr.Type); {0}", flr.Color); {0}", flr.Arrangement); {0:C}", flr.UnitPrice);

} }

This would produce:
Flower Type: 0 Flower Color: 0 Arrangement: Price: $0.00 Press any key to continue . . .

If you declare a variable of a class in your program, when the program comes up, the compiler reserves enough memory space for each member of the class. The memory space reserved for each member variable is filled with an initial value based on its type. For a string object, the space would be left empty. For an integer type, the space would be filled with 0. A better way to take care of this type is to provide a value whose role would be to initialize the member variables with the values of your choice. A method that initializes an object can return any value but it is preferable to be of type void because its primary purpose is to reset the values. Since this method would give a starting value to all member variables that need to be initialized, it should have an equivalent argument for each of the member variables that it would initialize. Here is an example:
public class Flower { public int Type; public int Color;

C# 3.0 Practical Learning

154

public char Arrangement; public double UnitPrice; public void Initializer(int tp, int clr, char arng, double price) { }

}

The method initializer does not have to initialize all members of the class. For example, the previous execution of the program shows that the member variables that are of type string are initialized with empty strings. In such a case, you may not have to initialize such variables. To implement a method initializer, simply assign its argument to the corresponding member variable of the class. Here are examples:
public class Flower { public int Type; public int Color; public char Arrangement; public double UnitPrice; public void Initializer(int tp, int clr, char arng, double price) { Type = tp; Color = clr; Arrangement = arng; UnitPrice = price; }

}

You can call a method initializer after declaring the instance of the class to give it initial values. Here is an example:
using System; public class Flower { public int Type; public int Color; public char Arrangement; public double UnitPrice; public void Initializer(int tp, int clr, char arng, double price) { Type = tp; Color = clr; Arrangement = arng; UnitPrice = price; } } public class Exercise { static int Main() { var flr = new Flower(); flr.Initializer(3, 7, 'V', 37.15D);

C# 3.0 Practical Learning

155

Console.WriteLine("Flower Type: Console.WriteLine("Flower Color: Console.WriteLine("Arrangement: flr.Arrangement); Console.WriteLine("Price: flr.UnitPrice); Console.WriteLine(""); return 0; } }

{0}", flr.Type); {0}", flr.Color); {0}", {0:C}",

This would produce:
Flower Type: Flower Color: Arrangement: Price: 3 7 V $37.15

Press any key to continue . . .

Using a method initializer, after initializing the object, you can use the values it holds as you see fit.

Default Constructor
A constructor is a special method that is created when the object comes to life. This particular method holds the same name as the class and it initializes the object whenever that object is created. When you create a class, if you don't declare a constructor, the compiler creates one for you; this is useful because it lets all other objects of the program know that the object exists. This compilercreated constructor is called the default constructor. If you want, you can create your own constructor. To create a constructor, declare a method that holds the same name as the class. Remember that the method must not return any value. Here is an example:
namespace FlowerShop { public class Flower { Flower() { } } }

When you declare an instance of the class, whether you use that object or not, a constructor for the object is created. When an instance of a class has been declared, the default constructor is called, whether the object is used or not. This is illustrated in the following program:
using System; namespace FlowerShop {

C# 3.0 Practical Learning

156

public class Flower { public int Type; public int Color; public char Arrangement; public decimal UnitPrice; public Flower() { Console.WriteLine("New Flower Order"); } } public class Exercise { static int Main() { var flr = new Flower(); return 0; } } }

This would produce:
New Flower Order Press any key to continue...

As you can see, even though the flr variable was not used, just its declaration was enough to signal it. You might find it sometimes convenient to create your own constructor because, whether you create an empty constructor or not, this does not negatively impact your program.

The Constructor Initializer
A constructor can be used to initialize the member variables of a class. As such, a constructor provides a valuable alternative to a method initializer, the type of method we saw earlier. To use a constructor to initialize the member variables of a class, provide as arguments the necessary variables that you intend to initialize. You don't have to initialize all member variables in the constructor, only those that need to be initialized. In fact, you should initialize only those members that you think the other objects would need when using this object. This means that your object may have fields that, either the external objects don't need to modify (or access) or the member variable(s) will be initialized later when called from the needed object(s). To implement a default constructor, you can just initialize the desired members of the class. For a member variable of a numeric type, you can just assign the desired constant to each. If the variable is a character, assign a single-quoted symbol to it. If the variable is a string, then assign a double-quoted value to the variable. Here are examples:
using System; namespace FlowerShop {

C# 3.0 Practical Learning

157

public class Flower { public int Type; public int Color; public char Arrangement; public decimal UnitPrice; public Flower() { Type Color Arrangement UnitPrice }

= = = =

1; 1; 'V'; 0M;

}

public class Program { static int Main() { var flr = new Flower(); Console.WriteLine("Flower Type: {0}", flr.Type); Console.WriteLine("Flower Color: {0}", flr.Color); Console.WriteLine("Arrangement: {0}", flr.Arrangement); Console.WriteLine("Price: {0:C}", flr.UnitPrice); Console.WriteLine(""); return 0;

} } }

Constructor Overloading
The default constructor is the favorite place to provide default values to the members of a class. Besides the default constructor, you can add as many constructors as you judge necessary. This feature of C# allows you to create various constructors for different reasons. This also means that the methods or constructors of a class can be overloaded. One of the rules of method overloading consists of having methods with different types of arguments. The most basic constructor you would create can use a single argument. When implementing a constructor that takes one argument, you should initialize the member that corresponds to the unique argument and initialize the other members with default values. Here is an example:
using System; namespace FlowerShop

C# 3.0 Practical Learning

158

{ public class Flower { public int Type; public int Color; public char Arrangement; public decimal UnitPrice; public Flower() { Type Color Arrangement UnitPrice }

= = = =

1; 1; 'V'; 0M; tp) tp; 1; 'V'; 0M;

public Flower(int { Type = Color = Arrangement = UnitPrice = } } }

If you create a class with only one constructor as in the current example, when declaring an instance of the class, you must use that constructor: you cannot use the default constructor that doesn't take an argument. When declaring the variable, initialize it with a constructor with parentheses and provide the value(s) in the parentheses of the constructor. Here is an example:
using System; namespace FlowerShop { public class Flower { public string Type; public string Color; public string Arrangement; public double UnitPrice; public Flower() { Type Color Arrangement UnitPrice }

= = = =

""; "Red"; "Basket"; 35.95D;

} }

public Flower(string tp) { Type = tp; Color = "Red"; Arrangement = "Basket"; UnitPrice = 35.95D;

C# 3.0 Practical Learning

159

public class Exercise { static int Main() { var flr = new Flower("Tulips"); Console.WriteLine("Flower Type: Console.WriteLine("Flower Color: Console.WriteLine("Arrangement: Console.WriteLine("Price: Console.WriteLine(""); return 0; {0}", flr.Type); {0}", flr.Color); {0}", flr.Arrangement); {0:C}", flr.UnitPrice);

} } }

This would produce:
Flower Type: Flower Color: Arrangement: Price: Tulips Red Basket $35.95

Press any key to continue . . .

In the same way, you can create different constructors for different initializations, although it would not be realistic to create a different constructor for each variable. If you create different constructors with different arguments to initialize (remember the rules of method overloading), when declaring the classes, make sure you initialize each instance with the right number of arguments; otherwise, the compiler would complain. If you create a class with only one constructor and that constructor has at least one argument, the default constructor would not be available anymore. If you want to access a default constructor of an object, you have two alternatives:
• •

If you don't create any constructor at all on a class, the default constructor would always be available whenever you invoke that class If you create at least one constructor on a class and supply at least one argument to that constructor, you must explicitly create a default constructor for your class.

The Destructor of a Class
As opposed to a constructor, a destructor is called when a program has finished using an object. A destructor does the cleaning behind the scenes. Like the default constructor, the compiler always creates a default destructor if you don't create one. Unlike the constructor, the destructor cannot be overloaded. This means that, if you decide to create a destructor, you can have only one. Like the default constructor, a destructor also has the same name as its class. This time, the name of the destructor starts with a tilde "~". To create a destructor, type ~ followed by the name of the class. Here is an example:

C# 3.0 Practical Learning

160

namespace FlowerShop { public class Flower { public string Type; public string Color; public string Arrangement; public decimal UnitPrice; public Flower() { Type = ""; Color = "Red"; Arrangement = "Basket"; UnitPrice = 35.95M; } public Flower(string tp) { Type = tp; Color = "Red"; Arrangement = "Basket"; UnitPrice = 35.95M; } ~Flower() { } } }

C# 3.0 Practical Learning

161

COMBINATIONS OF CLASSES
Classes

Combinations

Class Nesting
A class can be created inside of another class. A class created inside of another is referred to as nested. 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 as you judge it necessary. 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() {

C# 3.0 Practical Learning

162

Console.WriteLine(" -= Inside =-"); } }

}

public Outside() { Console.WriteLine(" =- Outside -="); }

public class Exercise { static int Main() { Outside Recto = new Outside(); Outside.Inside Ins = new Outside.Inside(); } } return 0;

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"; } public static void Show() { Console.WriteLine("Show me the wonderful world of C# Programming"); } } public Outside() { Console.WriteLine(" =- The Parent -="); } public void Display() {

C# 3.0 Practical Learning

163

} }

Console.WriteLine(Inside.InMessage); Inside.Show();

class Exercise { static int Main() { Outside Recto = new Outside(); Outside.Inside Ins = new Outside.Inside(); Recto.Display(); return 0;

} }

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();

C# 3.0 Practical Learning

164

} } public class Exercise { static int Main() { Outside Recto = new Outside(); Outside.Inside Ins = new Outside.Inside(); Recto.Display(); Console.WriteLine(); Ins.FieldFromOutside(); return 0;

} }

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 } // 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); }

raining";

C# 3.0 Practical Learning

165

} // 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() { Console.WriteLine(insider.InMessage); } // Declare a variable to access the nested class Inside insider = new Inside(); } public class Exercise { static int Main() { Outside Recto = new Outside(); Outside.Inside Ins = new Outside.Inside(); Ins.Show(); Recto.Display(); return 0; } }

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 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 Point { internal short x; internal short y; }

C# 3.0 Practical Learning

166

A field is a member variable created from another class instead of a primitive type. To use one class as a member variable of another class, simply declare its variable as you would proceed with any of the member variables we have declared so far. Here is an example:
public class Point { internal short x; internal short y; } public class CoordinateSystem { public Point Start; }

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, 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. 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 program.

Practical Learning: Using a Class as a Field
1. Start a new Console Application and name it ElectonicStore1 2. To create a new class, in the Solution Explorer, right-click the name of the project, position the mouse on Add and click Class... 3. Set the Name to StoreItem and click Add 4. Complete the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace ElectronicStore1 { public class StoreItem { private long nbr; private char cat; private string mk; private string mdl; private double price; public long GetItemNumber() { return nbr; } public void SetItemNumber(long number) { this.nbr = number;

C# 3.0 Practical Learning

167

} public char GetCategory() { return cat; } public void SetCategory(char category) { this.cat = category; } public string GetMake() { return mk; } public void SetMake(string make) { this.mk = make; } public string GetModel() { return mdl; } public void SetModel(string model) { this.mdl = model; } public double GetUnitPrice() { return price; } public void SetUnitPrice(double unitPrice) { this.price = unitPrice; } } }

5. Access the Program.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace ElectronicStore1 { class Program { static void Main() { string strTitle1 = "=-= Nearson Electonics =-=\n"; string strTitle2 = "******* Store Items ******";

C# 3.0 Practical Learning

168

} } }

Console.WriteLine();

6. Save all

Returning a Class or Passing a Class
Returning a Class From a Method
Like a value from a regular type, you can return a class value 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:
public class Point { internal short x; internal short y; } public class CoordinateSystem { private Point Start; private Point End; public Point GetThePoint() { } }

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. Here is an example:
public class Point { internal short x; internal short y; } public class CoordinateSystem { private Point Start; private Point End; public Point GetThePoint() { Point pt = new Point(); Console.Write("Enter the x coordinate of the point: "); pt.x = short.Parse(Console.ReadLine()); Console.Write("Enter the y coordinate of the point: "); pt.y = short.Parse(Console.ReadLine());

C# 3.0 Practical Learning

169

return pt; } }

Once a method has returned a value of a class, the value can be used as normally as possible.

Passing a Class 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. As done for the arguments of primitive types, you can pass more than one class as argument to a method. Here are different examples:
using System; namespace Geometry { public class Point { internal short x; internal short y; } public class CoordinateSystem { public Point Start; public Point End; public Point GetThePoint() { Point pt = new Point(); Console.Write("Enter the x coordinate of the point: "); pt.x = short.Parse(Console.ReadLine()); Console.Write("Enter the y coordinate of the point: "); pt.y = short.Parse(Console.ReadLine()); return pt; } public double DistanceFromOrigin(Point pt) { double sqr1 = Math.Pow(pt.x, 2); double sqr2 = Math.Pow(pt.y, 2); double distance = Math.Sqrt(sqr1 + sqr2); return distance; } public double DistanceBetween2Points(Point pt1, Point pt2) { double sqr1 = Math.Pow(pt2.x - pt1.x, 2); double sqr2 = Math.Pow(pt2.y - pt1.y, 2); double distance = Math.Sqrt(sqr1 + sqr2); return distance; }

}

C# 3.0 Practical Learning

170

public class Program { private static CoordinateSystem IdentifyCoordinates() { CoordinateSystem coord = new CoordinateSystem(); Console.WriteLine("Start Point"); coord.Start = coord.GetThePoint(); Console.WriteLine("End Point"); coord.End = coord.GetThePoint(); return coord; } private static void Show(CoordinateSystem c) { Console.WriteLine("Coordinate System"); Console.WriteLine("Starting Point: P({0}, {1})", c.Start.x, c.Start.y); Console.WriteLine("Ending Point: Q({0}, {1})", c.End.x, c.End.y); Console.WriteLine("Distance Between Both Points: {0:F}", c.DistanceBetween2Points(c.Start, c.End)); } static int Main() { CoordinateSystem coord = IdentifyCoordinates(); Console.WriteLine(); Show(coord); return 0; } } }

Here is an example of running the program:
Start Point Enter the x Enter the y End Point Enter the x Enter the y coordinate of the point: -2 coordinate of the point: 2 coordinate of the point: 3 coordinate of the point: -6

Coordinate System Starting Point: P(-2, 2) Ending Point: Q(3, -6) Distance Between Both Points: 9.43 Press any key to continue . . .

Because classes are always used as references, 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:
using System; namespace ConsoleApplication1 {

C# 3.0 Practical Learning

171

public class Point { internal short x; internal short y; } public class CoordinateSystem { public Point Start; public Point End; public Point GetThePoint() { Point pt = new Point(); Console.Write("Enter the x coordinate of the point: "); pt.x = short.Parse(Console.ReadLine()); Console.Write("Enter the y coordinate of the point: "); pt.y = short.Parse(Console.ReadLine()); return pt;

}

public double DistanceFromOrigin(ref Point pt) { double sqr1 = Math.Pow(pt.x, 2); double sqr2 = Math.Pow(pt.y, 2); double distance = Math.Sqrt(sqr1 + sqr2); return distance; } public double DistanceBetween2Points(ref Point pt1, ref Point pt2) { double double double return } } sqr1 = Math.Pow(pt2.x - pt1.x, 2); sqr2 = Math.Pow(pt2.y - pt1.y, 2); distance = Math.Sqrt(sqr1 + sqr2); distance;

public class Program { private static CoordinateSystem IdentifyCoordinates() { CoordinateSystem coord = new CoordinateSystem(); Console.WriteLine("Start Point"); coord.Start = coord.GetThePoint(); Console.WriteLine("End Point"); coord.End = coord.GetThePoint(); } return coord;

private static void Show(CoordinateSystem c) { Console.WriteLine("Coordinate System"); Console.WriteLine("Starting Point: P({0}, {1})", c.Start.x, c.Start.y);

C# 3.0 Practical Learning

172

Console.WriteLine("Ending Point: c.End.y); c.End)); }

Q({0}, {1})", c.End.x,

Console.WriteLine("Distance Between Both Points: {0:F}", c.DistanceBetween2Points(ref c.Start, ref

static int Main() { CoordinateSystem coord = IdentifyCoordinates(); Console.WriteLine(); Show(coord); return 0;

} } }

Practical Learning: Return a Class or Passing One as Argument
1. To return a class or pass it as argument, change the Program.cs file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace ElectronicStore1 { public class SaleItem { double DiscountAmount; double NetPrice; int Quantity; double SaleTotal; public double GetDiscountRate() { Console.Write( "Discount Applied (Enter 0 to 100, 0 if no discount): "); double discount = double.Parse(Console.ReadLine()); return discount; } public int GetQuantity() { Console.Write("Enter Quantity: "); int q = int.Parse(Console.ReadLine()); return q; } public StoreItem Create() { long itemNumber; char category; string make; string model;

C# 3.0 Practical Learning

173

double discount; double price; StoreItem saleItem = new StoreItem(); Console.Write("Enter the Item #: "); itemNumber = long.Parse(Console.ReadLine()); Console.WriteLine("Category"); Console.WriteLine("A - Audio Cables"); Console.WriteLine("B - Instructional and Tutorials (Books)"); Console.WriteLine("C - Cell Phones and Accessories"); Console.WriteLine("D - Bags and Cases"); Console.WriteLine("E - Headphones"); Console.WriteLine("F - Instructional and Tutorials (VHS & DVD)"); Console.WriteLine("G - Digital Cameras"); Console.WriteLine("H - Cables and Connectors"); Console.WriteLine("I - PDAs and Accessories"); Console.WriteLine("J - Telephones and Accessories"); Console.WriteLine("K - Surge Protector"); Console.WriteLine("L - TVs and Videos"); Console.WriteLine("U - Unknown"); Console.Write("Your Choice? "); category = char.Parse(Console.ReadLine()); Console.Write("Make: "); make = Console.ReadLine(); Console.Write("Model: "); model = Console.ReadLine(); Console.Write("Unit Price: "); price = double.Parse(Console.ReadLine()); saleItem.SetItemNumber(itemNumber); saleItem.SetCategory(category); saleItem.SetMake(make); saleItem.SetModel(model); saleItem.SetUnitPrice(price); return saleItem; } public void ShowSaleItem(StoreItem item) { double discountRate = GetDiscountRate(); int quantity = GetQuantity(); DiscountAmount = item.GetUnitPrice() * discountRate / 100; NetPrice = item.GetUnitPrice() - DiscountAmount; SaleTotal = NetPrice * quantity; Console.WriteLine("\nStore Item Description"); Console.WriteLine("Item Number: {0}", item.GetItemNumber()); Console.WriteLine("Category: {0}", item.GetCategory()); Console.WriteLine("Make {0}", item.GetMake()); Console.WriteLine("Model: {0}", item.GetModel()); Console.WriteLine("Unit Price: {0:C}", item.GetUnitPrice()); Console.WriteLine("Discount Rate: {0:P}", discountRate/100); Console.WriteLine("Discount Amount: {0:C}", DiscountAmount); Console.WriteLine("Price/Item: {0:C}", NetPrice);

C# 3.0 Practical Learning

174

} }

Console.WriteLine("Quantity: Console.WriteLine("Sale Total:

{0}", quantity); {0:C}", SaleTotal);

public class Program { static void Main() { StoreItem item = new StoreItem(); SaleItem sale = new SaleItem(); string strTitle1 = "=-= Nearson Electonics =-=\n"; string strTitle2 = "******* Store Items ******"; Console.WriteLine(strTitle1); Console.WriteLine(strTitle2); item = sale.Create(); sale.ShowSaleItem(item); Console.WriteLine(); } } }

2. Execute the application. Here is an example:
=-= Nearson Electonics =-= ******* Store Items ****** Enter the Item #: 927374 Category A - Audio Cables B - Instructional and Tutorials (Books) C - Cell Phones and Accessories D - Bags and Cases E - Headphones F - Instructional and Tutorials (VHS & DVD) G - Digital Cameras H - Cables and Connectors I - PDAs and Accessories J - Telephones and Accessories K - Surge Protector L - TVs and Videos U - Unknown Your Choice? L Make: NEC Model: VT48 Video Projector Unit Price: 705.95 Discount Applied (Enter 0 to 100, 0 if no discount): 15 Enter Quantity: 1 Store Item Description Item Number: 927374 Category: L Make NEC Model: VT48 Video Projector

C# 3.0 Practical Learning

175

Unit Price: Discount Rate: Discount Amount: Price/Item: Quantity: Sale Total:

$705.95 15.00 % $105.89 $600.06 1 $600.06

Press any key to continue . . .

3. Return to your programming environment

Involving a Class and its Own Methods
Passing a Class as its Own Argument
An instance of a class can be passed as an argument to one of its own methods (if you have programmed in C++, an example of this implementation is the copy constructor; although you can legitimately create a copy constructor in C#, it does not have the exact same concept as in C++, probably because C# has the Equals() method, which is actually a concept of the .NET Framework). To do this, you primarily pass the argument as if it were any class. Here is an example:
public class Point { internal int x; internal int y; public void Equivalent(Point Same) { } }

Then, in the body of the method, do whatever you want. You can, or you may not, use the argument. Still, if you decide to use the argument, know that all of the other members of the class are available through the argument. Probably the simplest way to use the argument is the assign each of of its values to the equivalent member of the class. Here is an example:
public class Point { internal int x; internal int y; public void Equivalent(Point Same) { this.x = Same.x; this.y = Same.y; }

}

When calling the method, make sure you pass an instance of the class to it. You can first create and define the class, then pass it. Here is an example:
using System;

C# 3.0 Practical Learning

176

public class Point { internal int x; internal int y; public void Equivalent(Point Same) { this.x = Same.x; this.y = Same.y; } } public class Program { private static void ShowPoint(Point pt) { Console.Write("Point Coordinates: "); Console.WriteLine("A({0}, {1})", pt.x, pt.y); } static int Main(string[] args) { Point pt = new Point(); pt.x = 4; pt.y = 6; ShowPoint(pt); Point One = new Point(); One.Equivalent(pt); ShowPoint(One); } } return 0;

This would produce:
Point Coordinates: A(4, 6) Point Coordinates: A(4, 6) Press any key to continue . . .

Instead of first declaring a variable of the class and initializing it, you can create an instance of the class in the parentheses of the calling method. To do this, you may need a constructor that can specify the values of the fields of the class so the argument can be rightfully initialized. Here is an example:
using System; public class Point { internal int x; internal int y; public Point() { } public Point(int XCoord, int YCoord)

C# 3.0 Practical Learning

177

{ this.x = XCoord; this.y = YCoord; } public void Equivalent(Point Same) { this.x = Same.x; this.y = Same.y; }

}

public class Program { private static void ShowPoint(Point pt) { Console.Write("Point Coordinates: "); Console.WriteLine("A({0}, {1})", pt.x, pt.y); } static int Main(string[] args) { Point pt = new Point(); pt.x = 4; pt.y = 6; ShowPoint(pt); Point One = new Point(); One.Equivalent(new Point(-3, 2)); ShowPoint(One); return 0; } }

Instead of a formal method, you can use a constructor of the class to pass an instance of the same class. Then, in the constructor, use the argument as you see fit, knowing that all the members of the class are available. Here is an example:
public class Point { internal int x; internal int y; public Point() { } public Point(int XCoord, int YCoord) { this.x = XCoord; this.y = YCoord; } public Point(Point Same) { this.x = Same.x; this.y = Same.y;

C# 3.0 Practical Learning

178

} }

Obviously the purpose of passing a class to one of its own methods is not to find its equivalent. The C# language (actually the .NET Framework) can also take care of that (through the Equals() built-in method). Instead, you can create a method that takes an instance of the same class but modifies that instance. For example, for our Point class, we may want to create a new point that is distanced by one unit from the current Point object. Here is an example of doing that:
using System; public class Point { internal int x; internal int y; public Point() { } public Point(int XCoord, int YCoord) { this.x = XCoord; this.y = YCoord; } public void Equivalent(Point Same) { this.x = Same.x; this.y = Same.y; } public void CreatePointOneUnitAway(Point AddUnit) { this.x = AddUnit.x + 1; this.y = AddUnit.y + 1; } } public class Program { private static void ShowPoint(Point pt) { Console.Write("Point Coordinates: "); Console.WriteLine("A({0}, {1})", pt.x, pt.y); } static int Main(string[] args) { Point pt = new Point(); pt.x = 4; pt.y = 6; ShowPoint(pt); Point One = new Point(); One.CreatePointOneUnitAway(pt);

C# 3.0 Practical Learning

179

ShowPoint(One); One.CreatePointOneUnitAway(new Point(-8, -3)); ShowPoint(One); return 0; } }

This would produce:
Point Point Point Press Coordinates: A(4, 6) Coordinates: A(5, 7) Coordinates: A(-7, -2) any key to continue . . .

Returning a Class From its Own Method
You can create a method in a class that returns an instance of the class. To start, on the left side of the method, enter the name of the class. Here is an example:
public class Point { public Point MethodName() { } }

There are various ways you can deal with the method. If you want to return a new value of the class, you can declare an instance of the class, initialize it, and then return it. Here is an example:
using System; public class Point { internal int x; internal int y; public Point() { } public Point(int XCoord, int YCoord) { this.x = XCoord; this.y = YCoord; } public Point(Point Same) { this.x = Same.x; this.x = Same.x; } public Point AdvanceBy5() { Point Some = new Point(); Some.x = 5;

C# 3.0 Practical Learning

180

} }

Some.y = 5; return Some;

public class Program { private static void ShowPoint(Point pt) { Console.Write("Point Coordinates: "); Console.WriteLine("A({0}, {1})", pt.x, pt.y); } static int Main(string[] args) { Point pt = new Point(); pt.x = 4; pt.y = 6; ShowPoint(pt); Point Away5 = pt.AdvanceBy5(); ShowPoint(Away5); return 0; } }

This would produce:
Point Coordinates: A(4, 6) Point Coordinates: A(5, 5) Press any key to continue . . .

Alternatively, you can declare an instance of the class, use the current values of the class combined with the those of the instance to get new values, and then return the instance. Here is an example:
using System; public class Point { internal int x; internal int y; public Point() { } public Point(int XCoord, int YCoord) { this.x = XCoord; this.y = YCoord; } public Point(Point Same) { this.x = Same.x; this.x = Same.x; }

C# 3.0 Practical Learning

181

}

public Point AdvanceBy5() { Point Some = new Point(); Some.x = this.x + 5; Some.y = this.y + 5; return Some; }

public class Program { private static void ShowPoint(Point pt) { Console.Write("Point Coordinates: "); Console.WriteLine("A({0}, {1})", pt.x, pt.y); } static int Main(string[] args) { Point pt = new Point(); pt.x = 4; pt.y = 6; ShowPoint(pt); Point Away5 = pt.AdvanceBy5(); ShowPoint(Away5); } } return 0;

This would produce:
Point Coordinates: A(4, 6) Point Coordinates: A(9, 11) Press any key to continue . . .

Remember that, to call the method, if it is not static, you will need to declare an instance of the class from where you are calling the method. The second type of implementation consists of modifying the instance of the class that is calling the method. For example, you can add values to its fields or you can perform any other operation you want on the members of the calling instance. is an example:
using System; public class Point { internal int x; internal int y; public Point() { } public Point(int XCoord, int YCoord) { this.x = XCoord;

C# 3.0 Practical Learning

182

this.y = YCoord; } public Point(Point Same) { this.x = Same.x; this.x = Same.x; } // This method adds 1 to each field of the class // to get a new point away North-East of the current point public Point CreatePointOneUnitAway() { this.x = this.x + 1; this.y = this.y + 1; return this; } }

public class Program { private static void ShowPoint(Point pt) { Console.Write("Point Coordinates: "); Console.WriteLine("A({0}, {1})", pt.x, pt.y); } static int Main(string[] args) { Point pt = new Point(); pt.x = 4; pt.y = 6; ShowPoint(pt); Point One = new Point(-8, 5); Point Another = One.CreatePointOneUnitAway(); ShowPoint(Another); return 0; } }

This would produce:
Point Coordinates: A(4, 6) Point Coordinates: A(-7, 6) Press any key to continue . . .

As we have learned now, you can create a method that takes an argument that is the same type as its parent class. In the method, you can access any member of the class, including calling the other methods of the class.

C# 3.0 Practical Learning

183

INTRODUCTION TO CONDITIONS
Boolean Variables
Introduction
When interacting with a computer, a user submits values to a running application. Some of these values are valid. Some other values must be rejected or changed. To take care of these, the values must be checked, examined, re-examined, etc. The validity of a value is checked against its type. For example, a number can be checked as being equal to another. A condition can be checked as being true. A measure can be checked as to whether it is higher than a certain threshold. To perform the necessary validations of values, the C# language provides some symbols, referred to as Boolean operators.

Practical Learning: Introducing Boolean Variables
1. Start Microsoft Visual C# 2. Create a new Console Application named FlowerShop1 3. To create a new class, on the main menu, click Project -> Add Class... 4. Set the Name of the class to Flower and click Add 5. Complete the Flower.cs file as follows:

C# 3.0 Practical Learning

184

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace FlowerShop1 { public class Flower { public int Type; public int Color; public char Arrangement; public decimal UnitPrice; public Flower() { Type = 0; Color = 0; Arrangement = 'B'; UnitPrice = 0.00M; } public Flower(int type) { Type = type; Color = 0; Arrangement = 'B'; UnitPrice = 0.00M; } color, public Flower(int type, int { char argn, decimal price) Type = type; Color = color; Arrangement = argn; UnitPrice = price; } } }

6. To create a new class, in the Solution Explorer, right-click the project name, position the mouse on Add and click Class... 7. Set the Name of the class to OrderProcessing and click Add 8. Complete the OrderProcessing.cs file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace FlowerShop1

C# 3.0 Practical Learning

185

{ public class OrderProcessing { public OrderProcessing() { FlowerOrder = new Flower(); } public Flower FlowerOrder; public int Quantity; public decimal GetTotalPrice() { return Quantity * FlowerOrder.UnitPrice; } } }

9. Access the Program.cs file and complete it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace FlowerShop1 { public class Program { private static OrderProcessing CreateFlowerOrder() { OrderProcessing order = new OrderProcessing(); int type, color, qty; char arrangement; decimal price; Console.WriteLine("======================="); Console.WriteLine("==-=-=Flower Shop=-=-=="); Console.WriteLine("-----------------------"); Console.WriteLine("Enter the Type of Flower Order"); Console.WriteLine("1. Roses"); Console.WriteLine("2. Lilies"); Console.WriteLine("3. Daisies"); Console.WriteLine("4. Carnations"); Console.WriteLine("5. Live Plant"); Console.WriteLine("6. Mixed"); Console.Write("Your Choice: "); type = int.Parse(Console.ReadLine()); Console.WriteLine("Enter the Color"); Console.WriteLine("1. Red"); Console.WriteLine("2. White"); Console.WriteLine("3. Yellow"); Console.WriteLine("4. Pink"); Console.WriteLine("5. Orange"); Console.WriteLine("6. Blue"); Console.WriteLine("7. Lavender"); Console.WriteLine("8. Mixed");

C# 3.0 Practical Learning

186

Console.Write("Your Choice: "); color = int.Parse(Console.ReadLine()); Console.WriteLine("Enter the Type of Arrangement"); Console.WriteLine("U. Bouquet"); Console.WriteLine("V. Vase"); Console.WriteLine("B. Basket"); Console.WriteLine("M. Mixed"); Console.Write("Your Choice: "); arrangement = char.Parse(Console.ReadLine()); Console.Write("Enter the Unit Price: "); price = decimal.Parse(Console.ReadLine()); Console.Write("Enter Quantity: "); qty = int.Parse(Console.ReadLine()); Flower flr = new Flower(type, color, arrangement, price); order.FlowerOrder = flr; order.Quantity = qty; } return order;

private static void ShowFlowerOrder(OrderProcessing order) { Console.WriteLine("======================="); Console.WriteLine("==-=-=Flower Shop=-=-=="); Console.WriteLine("-----------------------"); Console.WriteLine("Flower Type: {0}", order.FlowerOrder.Type); Console.WriteLine("Flower Color: {0}", order.FlowerOrder.Color); Console.WriteLine("Arrangement: {0}", order.FlowerOrder.Arrangement); Console.WriteLine("Price: {0:C}", order.FlowerOrder.UnitPrice); Console.WriteLine("Quantity: {0}", order.Quantity); Console.WriteLine("Total Price: {0:C}", order.GetTotalPrice()); Console.WriteLine("======================="); } static void Main(string[] args) { OrderProcessing flower = CreateFlowerOrder(); Console.WriteLine(); ShowFlowerOrder(flower); Console.WriteLine();

} } }

10.

Execute the application and test it. Here is an example:

======================= ==-=-=Flower Shop=-=-== -----------------------

C# 3.0 Practical Learning

187

Enter the Type of Flower Order 1. Roses 2. Lilies 3. Daisies 4. Carnations 5. Live Plant 6. Mixed Your Choice: 4 Enter the Color 1. Red 2. White 3. Yellow 4. Pink 5. Orange 6. Blue 7. Lavender 8. Mixed Your Choice: 6 Enter the Type of Arrangement U. Bouquet V. Vase B. Basket M. Mixed Your Choice: V Enter the Unit Price: 37.95 Enter Quantity: 2 ======================= ==-=-=Flower Shop=-=-== ----------------------Flower Type: 4 Flower Color: 6 Arrangement: V Price: $37.95 Quantity: 2 Total Price: $75.90 ======================= Press any key to continue . . .

11.

Close the DOS window

Declaring a Boolean Variable
A variable is referred to as Boolean if it can hold a value that is either true or false. To declare a Boolean variable, you can use either the var or the bool keyword. Here is an example:
using System; public class Exercise { static int Main() { bool DrinkingUnderAge; } } return 0;

C# 3.0 Practical Learning

188

Alternatively, you can declare a Boolean variable using the Boolean data type. The Boolean data type is part of the System namespace. Here is an example:
using System; public class Exercise { static int Main() { bool DrinkingUnderAge; Boolean TheFloorIsCoveredWithCarpet; } } return 0

After the variable has been declared, you must initialize it with a true or a false value. In fact, if you declare it as var, you must initialize it. Here is an example:
using System; public class Exercise { static int Main() { var DrinkingUnderAge = true; return 0; } }

To display the value of a Boolean variable on the console, you can type its name in the parentheses of the Write() or the WriteLine() methods of the Console class. Here is an example:
using System; public class Exercise { static int Main() { var DrinkingUnderAge = true; Console.WriteLine("Drinking Under Age: {0}", DrinkingUnderAge); return 0; } }

This would produce:
Drinking Under Age: True Press any key to continue . . .

At any time and when you judge it necessary, you can change the value of the Boolean variable by assigning it a true or false value. Here is an example:
using System; public class Exercise

C# 3.0 Practical Learning

189

{ static int Main() { var DrinkingUnderAge = true; Console.WriteLine("Drinking Under Age: {0}", DrinkingUnderAge); DrinkingUnderAge = false; Console.WriteLine("Drinking Under Age: {0}", DrinkingUnderAge); return 0;

} }

This would produce:
Drinking Under Age: True Drinking Under Age: False Press any key to continue . . .

Retrieving the Value of a Boolean Variable
As reviewed for the other data types, you can request the value of a Boolean variable from the user. In this case, the user must type either True (or true) or False (or false) and you can retrieve it using the Read() or the ReadLine() methods of the Console class. Here is an example:
using System; public class Exercise { static int Main() { var DrivingUnderAge = false; Console.WriteLine("Were you driving under age?"); Console.Write("If Yes, enter True. Otherwise enter False: "); DrivingUnderAge = bool.Parse(Console.ReadLine()); Console.WriteLine("\nWas Driving Under Age: {0}\n", DrivingUnderAge); return 0; } }

Here is an example of running the program:
Were you driving under age? If Yes, enter True. Otherwise enter False: true Was Driving Under Age: True Press any key to continue . . .

Creating a Boolean Field

C# 3.0 Practical Learning

190

Like the other types of variables we used in previous lessons, a Boolean variable can be made a field of a class. You declare it like any other variable, using the bool keyword or the Boolean data type. Here is an example:
public class House { public public public public public public public char TypeOfHome; int Bedrooms; float Bathrooms; byte Stories; bool HasCarGarage; int YearBuilt; double Value;

}

When initializing an object that has a Boolean variable as a member, simply assign true or false to the variable. In the same way, you can retrieve or check the value that a Boolean member variable is holding by simply accessing it. Here are examples:
using System; public class House { public char TypeOfHome; public int Bedrooms; public float Bathrooms; public byte Stories; public bool HasCarGarage; public int YearBuilt; public double Value; } public class Program { static int Main() { var Condominium = new { HasCarGarage = false, YearBuilt = 2002, Bathrooms = 1.5F, Stories = 18, Value = 155825, Bedrooms = 2, TypeOfHome = 'C' }; Console.WriteLine("=//= Altair Realty =//="); Console.WriteLine("=== Property Listing ==="); Console.WriteLine("Type of Home: {0}", Condominium.TypeOfHome); Console.WriteLine("Number of Bedrooms: {0}", Condominium.Bedrooms); Console.WriteLine("Number of Bathrooms: {0}", Condominium.Bathrooms); Console.WriteLine("Number of Stories: {0}", Condominium.Stories);

C# 3.0 Practical Learning

191

Console.WriteLine("Year Built: Condominium.YearBuilt); Console.WriteLine("Has Car Garage: Condominium.HasCarGarage); Console.WriteLine("Monetary Value: Condominium.Value); } } return 0;

{0}", {0}", {0}\n",

This would produce:
=//= Altair Realty =//= === Property Listing === Type of Home: C Number of Bedrooms: 2 Number of Bathrooms: 1.5 Number of Stories: 18 Year Built: 2002 Has Car Garage: False Monetary Value: 155825 Press any key to continue . . .

Boolean Arguments
Like parameters of the other types, you can pass an argument of type bool or Boolean to a method. Such an argument would be treated as holding a true or false value.

Enumerations
Introduction
Consider that, when creating a program for a real estate company that sells houses, you want the program to ask a customer the type of house that he or she wants to purchase and/or the type of garage that the desired house should have. Here is an example:
using System; public class Exercise { static int Main() { int TypeOfHouse = 0; int TypeOfGarage = 0; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1 - Single Family"); Console.WriteLine("2 - Townhouse"); Console.WriteLine("3 - Condominium"); Console.Write("Your Choice: ");

C# 3.0 Practical Learning

192

TypeOfHouse = int.Parse(Console.ReadLine()); Console.WriteLine("Enter the type of garage you want"); Console.WriteLine("0 - Doesn't matter"); Console.WriteLine("1 - Interior"); Console.WriteLine("2 - Exterior"); Console.Write("Your Choice: "); TypeOfGarage = int.Parse(Console.ReadLine()); Console.WriteLine("\nHouse Type: {0}", TypeOfHouse); Console.WriteLine("Garage Type: {0}", TypeOfGarage); return 0; } }

Here is an example of running the program:
Enter the type of house you want to purchase 1 - Single Family 2 - Townhouse 3 - Condominium Your Choice: 3 Enter the type of garage you want 0 - Doesn't matter 1 - Interior 2 - Exterior Your Choice: 1 House Type: 3 Garage Type: 1 Press any key to continue . . .

For such a program, the numbers can be vague. 1 can be considered a general number but, in our program, it can represent a Single Family house or an Interior type of garage. At the same time, our program uses the constant 1 in particular meaningful ways. To make it possible to give more meaning to a constant number, when the number can be made part of a series, C# allows you to create a type of list. An enumeration is a series of constant integers that each has a specific position in the list and can be recognized by a meaningful name. Based on this, instead of just remembering that the constant 1 represents Single Family, you can create a list that has that type of house. In another list, instead of using 1 again, you can give it a name. Consequently, in each list, although the constant 1 would still be considered, at least it would mean something precise. To create an enumeration, you use the enum keyword, followed by the name of the enumeration, followed by a name for each item of the list. The name of the enumerator and the name of each item of the list follows the rules we reviewed for names. The formula of creating an enumeration is:
enum Series_Name {Item1, Item2, Item_n};

Here is an example:
using System; public class Exercise

C# 3.0 Practical Learning

193

{ enum HouseType { Unknown, SingleFamily, TownHouse, Condominium } static int Main() { return 0; } }

Declaring an Enumeration Variable
After creating an enumeration, each member of the enumeration holds a value of a natural number, such as 0, 4, 12, 25, etc. In C#, an enumeration cannot hold character values (of type char). After creating an enumeration, you can declare a variable from it. Here is an example:
using System; public class Exercise { enum HouseType { Unknown, SingleFamily, TownHouse, Condominium } static int Main() { HouseType propType; } } return 0;

Just as done with the other types, you can use the var keyword to declare a variable of an enumeration type.

Initializing an Enumeration Variable
After declaring a variable for an enumeration, to initialize it, specify which member of the enumeration would be assigned to the variable. You should only assign a known member of the enumeration. To do this, on the right side of the assignment operator, type the name of the enumeration, followed by the period operator, and followed by the member whose value you want to assign. Here is an example:
using System; public class Exercise { enum HouseType { Unknown, SingleFamily, TownHouse, Condominium } static int Main() { var propType = HouseType.SingleFamily; } } return 0;

C# 3.0 Practical Learning

194

You can also find out what value the declared variable is currently holding. For example, you can display it on the console using Write() or WriteLine(). Here is an example:
using System; public class Exercise { enum HouseType { Unknown, SingleFamily, TownHouse, Condominium } static int Main() { var propType = HouseType.SingleFamily; Console.WriteLine("House Type: } } return 0; {0}", propType);

This would produce:
House Type: SingleFamily Press any key to continue . . .

An enumeration is in fact a list of numbers where each member of the list is identified with a name. By default, the first item of the list has a value of 0, the second has a value of 1, and so on. For example, on the HouseType enumeration, Unknown has a value of 0 while Townhouse has a value of 2. These are the default values. If you don't want these values, you can specify the value of one or each member of the list. Suppose you want the Unknown member in the above enumeration to have a value of 5. To do this, use the assignment operator "=" to give the desired value. The enumerator would be:
using System; public class Exercise { enum HouseType { Unknown = 5, SingleFamily, TownHouse, Condominium } static int Main() { return 0; }

}

In this case, Unknown now would have a value of 5, SingleFamily would have a value of 6 because it follows a member whose value is 1 (thus 5 + 1 = 6). Townhouse would have a value of 7, and Condominium would have a value of 8. You can also assign a value to more than one member of an enumeration. Here is an example:
using System; public class Exercise { enum HouseType { Unknown = 3, SingleFamily = 12, TownHouse, Condominium = 8 }

C# 3.0 Practical Learning

195

}

static int Main() { return 0; }

In this case, Townhouse would have a value of 13 because it follows SingleFamily that has a value of 12.

Enumerations Visibility
By default, if you create an enumeration the way we have proceeded so far, it would be available only in the project it belongs to. As done for a class, you can control an enumeration's accessibility outside of its project. This means that you can hide or make it visible outside of its project. To do this, you can precede it with the private or the public keyword. Here is an example:
using System; public class Exercise { public enum HouseType { Unknown, SingleFamily, TownHouse, Condominium } static int Main() { HouseType propType = HouseType.SingleFamily; Console.WriteLine("House Type: return 0; {0}", propType);

} }

An Enumeration as a Member Variable
After creating an enumeration, you can use it as a data type to declare a variable. To create a field that is of an enumeration type, follow the same rules as done for the primitive types: the name of the enumeration, followed by the name of the variable, and followed by a semi-colon. Here is an example:
public enum HouseType { Unknown, SingleFamily, TownHouse, Condominium } public class House { HouseType PropertyType; }

C# 3.0 Practical Learning

196

In the same way, you can declare as many enumeration variables as you want. After declaring the variable, to initialize it, assign it the desired member of the enumeration. Here is an example:
public enum HouseType { Unknown, SingleFamily, TownHouse, Condominium } public class House { HouseType PropertyType; public House() { PropertyType = HouseType.Unknown; }

}

Once the member variable has been initialized, you can use it as you see fit as we will learn and practice in future sections and lessons. At a minimum, you can pass it to Write() or WriteLine() to display its value. Here is an example:
using System; public enum HouseType { Unknown, SingleFamily, TownHouse, Condominium } public class House { public HouseType PropertyType; public House() { PropertyType = HouseType.Unknown; } public void Display() { Console.WriteLine("Property Type: {0}", PropertyType); } } public class Exercise { static int Main() { var propType = new House(); propType.Display(); Console.WriteLine(); propType.PropertyType = HouseType.SingleFamily;

C# 3.0 Practical Learning

197

propType.Display(); Console.WriteLine(); } } return 0;

This would produce:
Property Type: Unknown Property Type: SingleFamily Press any key to continue . . .

Using it as normal data type, you can create a method that returns an enumeration. You can also pass an enumeration to a method as argument.

Practical Learning: Creating and Using Enumerations
1. Access the Flower.cs file 2. To create some enumerations, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace FlowerShop1 { public enum FlowerType { Roses = 1, Lilies, Daisies, Carnations, LivePlant, Mixed } public enum FlowerColor { Red = 1, White, Yellow, Pink, Orange, Blue, Lavender, Mixed } public enum FlowerArrangement { Bouquet = 1, Vase, Basket,

C# 3.0 Practical Learning

198

Mixed } public class Flower { public FlowerType Type; public FlowerColor Color; public FlowerArrangement Arrangement; public decimal UnitPrice; public Flower() { Type = FlowerType.Mixed; Color = FlowerColor.Mixed; Arrangement = FlowerArrangement.Vase; UnitPrice = 0.00M; } public Flower(FlowerType type) { Type = type; Color = FlowerColor.Mixed; Arrangement = FlowerArrangement.Vase; UnitPrice = 0.00M; } public Flower(FlowerType type, FlowerColor color, FlowerArrangement argn, decimal price) { Type = type; Color = color; Arrangement = argn; UnitPrice = price; }

} }

3. Access the Program.cs file 4. To use the enumerations, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace FlowerShop1 { public class Program { private static OrderProcessing CreateFlowerOrder() { OrderProcessing order = new OrderProcessing(); int type, color, qty; int arrangement; decimal price; Console.WriteLine("======================="); Console.WriteLine("==-=-=Flower Shop=-=-=="); Console.WriteLine("-----------------------");

C# 3.0 Practical Learning

199

Console.WriteLine("Enter the Type of Flower Order"); Console.WriteLine("1. Roses"); Console.WriteLine("2. Lilies"); Console.WriteLine("3. Daisies"); Console.WriteLine("4. Carnations"); Console.WriteLine("5. Live Plant"); Console.WriteLine("6. Mixed"); Console.Write("Your Choice: "); type = int.Parse(Console.ReadLine()); Console.WriteLine("Enter the Color"); Console.WriteLine("1. Red"); Console.WriteLine("2. White"); Console.WriteLine("3. Yellow"); Console.WriteLine("4. Pink"); Console.WriteLine("5. Orange"); Console.WriteLine("6. Blue"); Console.WriteLine("7. Lavender"); Console.WriteLine("8. Mixed"); Console.Write("Your Choice: "); color = int.Parse(Console.ReadLine()); Console.WriteLine("Enter the Type of Arrangement"); Console.WriteLine("1. Bouquet"); Console.WriteLine("2. Vase"); Console.WriteLine("3. Basket"); Console.WriteLine("4. Mixed"); Console.Write("Your Choice: "); arrangement = int.Parse(Console.ReadLine()); Console.Write("Enter the Unit Price: "); price = decimal.Parse(Console.ReadLine()); Console.Write("Enter Quantity: "); qty = int.Parse(Console.ReadLine()); Flower flr = new Flower((FlowerType)type, (FlowerColor)color, (FlowerArrangement)arrangement, price); order.FlowerOrder = flr; order.Quantity = qty; } return order;

private static void ShowFlowerOrder(OrderProcessing order) { Console.WriteLine("======================="); Console.WriteLine("==-=-=Flower Shop=-=-=="); Console.WriteLine("-----------------------"); Console.WriteLine("Flower Type: {0}", order.FlowerOrder.Type); Console.WriteLine("Flower Color: {0}", order.FlowerOrder.Color); Console.WriteLine("Arrangement: {0}", order.FlowerOrder.Arrangement); Console.WriteLine("Price: {0:C}", order.FlowerOrder.UnitPrice); Console.WriteLine("Quantity: {0}", order.Quantity);

C# 3.0 Practical Learning

200

Console.WriteLine("Total Price: {0:C}", order.GetTotalPrice()); Console.WriteLine("======================="); } static void Main(string[] args) { OrderProcessing flower = CreateFlowerOrder(); Console.WriteLine(); ShowFlowerOrder(flower); Console.WriteLine();

} } }

5. Execute the application and process an order. Here is an example:
======================= ==-=-=Flower Shop=-=-== ----------------------Enter the Type of Flower Order 1. Roses 2. Lilies 3. Daisies 4. Carnations 5. Live Plant 6. Mixed Your Choice: 5 Enter the Color 1. Red 2. White 3. Yellow 4. Pink 5. Orange 6. Blue 7. Lavender 8. Mixed Your Choice: 7 Enter the Type of Arrangement 1. Bouquet 2. Vase 3. Basket 4. Mixed Your Choice: 3 Enter the Unit Price: 35.95 Enter Quantity: 4 ======================= ==-=-=Flower Shop=-=-== ----------------------Flower Type: LivePlant Flower Color: Lavender Arrangement: Basket Price: $35.95 Quantity: 4 Total Price: $143.80 =======================

C# 3.0 Practical Learning

201

Press any key to continue . . .

6. Close the DOS window

Logical Operators
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 values 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 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 a logical 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). 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 or it is false. 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 or as false even if it can change at another time. For example, suppose that, in a certain year, a statement is formulated as "This year, the month of February has 28 days". Although allowed, you C# 3.0 Practical Learning
202

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 (not if, but when).

The Equality Operator ==
To compare two variables for equality, C# uses the == operator. The formula used 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 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; public class Exercise { static int Main() { var Value1 = 15; var Value2 = 24;

C# 3.0 Practical Learning

203

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); } } return 0;

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 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. Here is an example:
using System; public class Exercise { static int Main() { bool HasAirCondition = true; bool DoesIt; Console.Write("HasAirCondition = ");

C# 3.0 Practical Learning

204

Console.WriteLine(HasAirCondition); DoesIt = !HasAirCondition; Console.Write("DoesIt = "); Console.WriteLine(DoesIt); } } return 0;

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 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; public class Exercise {

C# 3.0 Practical Learning

205

static { var var var

int Main() Value1 = 212; Value2 = -46; Value3 = (Value1 != Value2);

Console.Write("Value1 = "); Console.WriteLine(Value1); Console.Write("Value2 = "); Console.WriteLine(Value2); Console.Write("Value3 = "); Console.Write(Value3); Console.WriteLine(); return 0; } }

The inequality is obviously the opposite of the equality.

The Comparison for a Lower Value <
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; public class Exercise { static int Main() { var Value1 = 15; var Value2 = (Value1 < 24);

C# 3.0 Practical Learning

206

Console.Write("Value 1 = "); Console.WriteLine(Value1); Console.Write("Value 2 = "); Console.WriteLine(Value2); Console.WriteLine(); } } return 0;

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 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; public class Exercise { static int Main() { var Value1 = 15; var Value2 = (Value1 <= 24); Console.Write("Value 1 = "); Console.WriteLine(Value1);

C# 3.0 Practical Learning

207

Console.Write("Value 2 = "); Console.WriteLine(Value2); Console.WriteLine(); return 0; } }

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

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 C# 3.0 Practical Learning
208

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:

Here is a summary table of the logical operators we have studied:

Operator

Meaning

Example

Opposite

== != <

Equality to Not equal to Less than Less than or equal to Greater than Greater than or equal to

a == b 12 != 7 25 < 84

!= == >=

<=

Cab <= Tab

>

>

248 > 55 Val1 >= Val2

<=

>=

<

Logically Incrementing or Decrementing a Value
Incrementing a Variable
C# 3.0 Practical Learning
209

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; public class Exercise { static int Main() { var Value = 12; Console.WriteLine("Techniques of incrementing a value"); Console.Write("Value = "); Console.WriteLine(Value); Value = Value + 1; Console.Write("Value = "); Console.WriteLine(Value); return 0; } }

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; public class Exercise { static int Main() { var Value = 12; Console.WriteLine("Techniques of incrementing a value"); Console.Write("Value = "); Console.WriteLine(Value); Value++; Console.Write("Value = "); Console.WriteLine(Value); return 0;

C# 3.0 Practical Learning

210

} }

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; public class Exercise { static int Main() { var 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); } } return 0;

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 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; public class Exercise { static int Main() { var Value = 12;

C# 3.0 Practical Learning

211

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); } } return 0;

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; public class Exercise { static int Main() { var 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); return 0; } }

This would produce:
Techniques of incrementing a value Value = 12 Value = 12 Value = 13

Decrementing a Value
C# 3.0 Practical Learning
212

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; public class Exercise { static int Main() { var Value = 12; Console.WriteLine("Techniques of decrementing a value"); Console.Write("Value = "); Console.WriteLine(Value); Value = Value - 1; Console.Write("Value = "); Console.WriteLine(Value); return 0; } }

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; public class Exercise { static int Main() { var Value = 12; Console.WriteLine("Techniques of decrementing a value"); Console.Write("Value = "); Console.WriteLine(Value); Value--; Console.Write("Value = "); Console.WriteLine(Value); return 0; } }

C# 3.0 Practical Learning

213

Pre Decrementing a Value
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; public class Exercise { static int Main() { var 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); } } return 0;

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; public class Exercise { static int Main() { var 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); return 0;

C# 3.0 Practical Learning

214

} }

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; public class Exercise { static int 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); return 0; } }

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. 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.

C# 3.0 Practical Learning

215

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; public class Exercise { static int Main() { var Value = 12.75; Console.WriteLine("Techniques of incrementing and decrementing a value"); Console.Write("Value = "); Console.WriteLine(Value); Value += 2.42; Console.Write("Value = "); Console.WriteLine(Value); } } return 0;

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; public class Exercise { static int Main() { var Value = 12.75; Console.WriteLine("Techniques of incrementing and decrementing a value"); Console.Write("Value = "); Console.WriteLine(Value); Value -= 2.42; Console.Write("Value = "); Console.WriteLine(Value); } } return 0;

This would produce: C# 3.0 Practical Learning
216

Techniques of incrementing and decrementing a value Value = 12.75 Value = 10.33

C# 3.0 Practical Learning

217

CONDITIONAL STATEMENTS
if a Condition is True
Introduction
A conditional statement is an expression that produces a true or false result. You can use that result as you see fit. To create the expression, you use the Boolean operators we studied in the previous lesson. In the previous lesson, we saw only how to perform the operations and how to get the results, not how to use them. To use the result of a Boolean operation, the C# programming language provides some specific conditional operators.

Practical Learning: Introducing Conditional Expressions
1. Start Microsoft Visual C# and create a Console Application named
ElectronicStore2

2. To create a new class, on the main menu, click Project -> Add Class... 3. Set the Name of the class to StoreItem and click Add 4. Complete the StoreItem.cs file as follows:

using using using using

System; System.Collections.Generic; System.Linq; System.Text;

namespace ElectronicStore2 { public enum ItemsCategories { Unknown, CablesAndConnectors, CellPhonesAndAccessories, Headphones, DigitalCameras, PDAsAndAccessories, TelephonesAndAccessories, TVsAndVideos, SurgeProtectors, Instructional } public class StoreItem

C# 3.0 Practical Learning

218

{ public public public public public public long ItemNumber; ItemsCategories Category; string Make; string Model; string Name; double UnitPrice;

// An item whose characteristics are not (yet) defined public StoreItem() { ItemNumber = 0; Category = ItemsCategories.Unknown; Make = "Unknown"; Model = "Unspecified"; Name = "N/A"; UnitPrice = 0.00D; } // An item that is known by its make, model, and unit price public StoreItem(long itmNbr, String make, String model, double price) { ItemNumber = itmNbr; Category = ItemsCategories.Unknown; Make = make; Model = model; Name = "N/A"; UnitPrice = price; } // An item that is known by its name and unit price public StoreItem(long itmNbr, String name, double price) { ItemNumber = itmNbr; Category = ItemsCategories.Unknown; Make = "Unknown"; Model = "Unspecified"; Name = name; UnitPrice = price; } // An item completely defined public StoreItem(long itmNbr, ItemsCategories category, String make, String model, double price) { ItemNumber = itmNbr; Category = category; Make = make; Model = model; UnitPrice = price; } } }

5. Save the file

if
Consider the following program: C# 3.0 Practical Learning
219

using System; public enum HouseType { Unknown, SingleFamily, TownHouse,

Condominium
}

public class Exercise { static int Main() { var type = HouseType.Unknown; var choice = 0; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); choice = int.Parse(Console.ReadLine()); Console.WriteLine("\nDesired House Type: {0}", type); return 0;

} }

Here is an example of running the program:
Enter the type of house you want to purchase 1. Single Family 2. TownHouse 3. Condominium You Choice? 3 Desired House Type: Unknown Press any key to continue . . .

C# 3.0 Practical Learning

220

To check if an expression is true and use its Boolean result, you can use the if operator. Its formula is:
if(Condition) Statement;

The Condition can be the type of Boolean operation we studied in the previous lesson. That is, it can have the following formula:
Operand1 BooleanOperator Operand2

If the Condition produces a true result, then the compiler executes the Statement. If the statement to execute is short, you can write it on the same line with the condition that is being checked. Here is an example:
using System; public enum HouseType { Unknown, SingleFamily, TownHouse, Condominium } public class Exercise { static int Main() { var type = HouseType.Unknown; var choice = 0; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); choice = int.Parse(Console.ReadLine()); if (choice == 1) type = HouseType.SingleFamily; Console.WriteLine("\nDesired House Type: {0}", type); return 0; } }

Here is an example of running the program:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 1 Desired House Type: SingleFamily Press any key to continue . . .

If the Statement is too long, you can write it on a different line than the if condition. Here is an example: C# 3.0 Practical Learning
221

using System; public enum HouseType { Unknown, SingleFamily, TownHouse, Condominium } public class Exercise { static int Main() { var type = HouseType.Unknown; var choice = 0; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); choice = int.Parse(Console.ReadLine()); if (choice == 1) type = HouseType.SingleFamily; Console.WriteLine("\nDesired House Type: {0}", type); return 0;

} }

You can also write the Statement on its own line even if the statement is short enough to fit on the same 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; public enum HouseType { Unknown, SingleFamily, TownHouse, Condominium } public class Exercise { static int Main() { var type = HouseType.Unknown; var choice = 0; Console.WriteLine("Enter the type of house you want to purchase");

C# 3.0 Practical Learning

222

Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); choice = int.Parse(Console.ReadLine()); if (choice == 1) { type = HouseType.SingleFamily; Console.WriteLine("\nDesired House Type: {0}", type); } return 0;

} }

If you omit the brackets, only the statement that immediately follows the condition would be executed. Just as you can write one if condition, you can write more than one. Here are examples:
using System; public enum HouseType { Unknown, SingleFamily, Townhouse, Condominium } public class Exercise { static int Main() { var type = HouseType.Unknown; var choice = 0; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); choice = int.Parse(Console.ReadLine()); if (choice type = if (choice type = if (choice type = == 1) HouseType.SingleFamily; == 2) HouseType.Townhouse; == 3) HouseType.Condominium;

Console.WriteLine("\nDesired House Type: {0}", type); return 0; } }

Here is an example of running the program: C# 3.0 Practical Learning
223

Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 3 Desired House Type: Condominium Press any key to continue . . .

Practical Learning: Using the Simple if Condition
1. Access the Program.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace ElectronicStore2 { public class Program { private static StoreItem CreateStoreItem() { StoreItem sItem = new StoreItem(); int Category; Console.WriteLine( "To create a store item, enter its information"); Console.Write("Item Number: "); sItem.ItemNumber = long.Parse(Console.ReadLine()); Console.WriteLine("Category"); Console.WriteLine("1. Unknown/Miscellaneous"); Console.WriteLine("2. Cables and Connectors"); Console.WriteLine("3. Cell Phones and Accessories"); Console.WriteLine("4. Headphones"); Console.WriteLine("5. Digital Cameras"); Console.WriteLine("6. PDAs and Accessories"); Console.WriteLine("7. Telephones and Accessories"); Console.WriteLine("8. TVs and Videos - Plasma / LCD"); Console.WriteLine("9. Surge Protector"); Console.WriteLine( "10. Instructional and Tutorials (VHS & DVD)TVs and Console.Write("Your Choice? "); category = int.Parse(Console.ReadLine()); if (Category == 1) sItem.Category = ItemsCategories.Unknown; if (Category == 2) sItem.Category = ItemsCategories.CablesAndConnectors; if (Category == 3) sItem.Category = ItemsCategories.CellPhonesAndAccessories; if (Category == 4) sItem.Category = ItemsCategories.Headphones; if (Category == 5) sItem.Category = ItemsCategories.DigitalCameras;

Videos");

C# 3.0 Practical Learning

224

if (Category == 6) sItem.Category = ItemsCategories.PDAsAndAccessories; if (Category == 7) sItem.Category = ItemsCategories.TelephonesAndAccessories; if (Category == 8) sItem.Category = ItemsCategories.TVsAndVideos; if (Category == 9) sItem.Category = ItemsCategories.SurgeProtectors; if (Category == 10) sItem.Category = ItemsCategories.Instructional; Console.Write("Make: "); sItem.Make = Console.ReadLine(); Console.Write("Model: "); sItem.Model = Console.ReadLine(); Console.Write("Unit Price: "); sItem.UnitPrice = decimal.Parse(Console.ReadLine()); } return sItem;

static void DescribeStoreItem(StoreItem item) { Console.WriteLine("Store Item Description"); Console.WriteLine("Item Number: {0}", item.ItemNumber); Console.WriteLine("Category: {0}", item.Category); Console.WriteLine("Make: {0}", item.Make); Console.WriteLine("Model: {0}", item.Model); Console.WriteLine("Unit Price: {0:C}", item.UnitPrice); } static void Main() { string strTitle1 = "=-= Nearson Electonics =-="; string strTitle2 = "******* Store Items ******"; StoreItem saleItem = CreateStoreItem(); Console.WriteLine(""); DescribeStoreItem(saleItem); } } }

2. Execute the application to see the result. Here is an example:

To create a store item, enter its information Item Number: 868264 Category

C# 3.0 Practical Learning

225

1. Unknown/Miscellaneous 2. Cables and Connectors 3. Cell Phones and Accessories 4. Headphones 5. Digital Cameras 6. PDAs and Accessories 7. Telephones and Accessories 8. TVs and Videos - Plasma / LCD 9. Surge Protector 10. Instructional and Tutorials (VHS & DVD)TVs and Videos Your Choice? 1 Make: Altec Lansing Model: VS4221 Computer Speakers Unit Price: 85.95 Store Item Description Item Number: 868264 Category: Unknown Make: Altec Lansing Model: VS4221 Computer Speakers Unit Price: $85.95 Press any key to continue . . .

3. Close the DOS window

if…else
Here is an example of what we learned in the previous section:

using System; public enum HouseType { Unknown, SingleFamily, Townhouse, Condominium }

public class Exercise { static int Main() { var type = HouseType.Unknown;

C# 3.0 Practical Learning

226

var choice = 0; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); choice = int.Parse(Console.ReadLine()); if (choice type = if (choice type = if (choice type = == 1) HouseType.SingleFamily; == 2) HouseType.Townhouse; == 3) HouseType.Condominium;

Console.WriteLine("\nDesired House Type: {0}", type); if (type == HouseType.SingleFamily) Console.WriteLine("\nDesired House Matched"); return 0; } }

If you use an if condition to perform an operation and if the result is true, we saw that you could execute the statement. As we saw in the previous section, any other result would be ignored. To address an alternative to an if condition, you can use the else condition. The formula to follow is:
if(Condition) Statement1; else Statement2;

Once again, the Condition can be a Boolean operation like those we studied in the previous lesson. If the Condition is true, then the compiler would execute Statement1. If the Condition is false, then the compiler would execute Statement2. Here is an example:
using System; public enum HouseType { Unknown, SingleFamily, Townhouse, Condominium } public class Program { static int Main() { var type = HouseType.Unknown; var choice = 0;

C# 3.0 Practical Learning

227

Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); choice = int.Parse(Console.ReadLine()); if (choice type = if (choice type = if (choice type = == 1) HouseType.SingleFamily; == 2) HouseType.Townhouse; == 3) HouseType.Condominium;

Console.WriteLine("\nDesired House Type: {0}", type); if (type == HouseType.SingleFamily) Console.WriteLine("Desired House Matched"); else Console.WriteLine("No House Desired"); return 0; } }

Here is an example of running the program:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 1 Desired House Type: SingleFamily Desired House Matched Press any key to continue . . .

Here is another example of running the program:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 2 Desired House Type: Townhouse No House Desired Press any key to continue . . .

Practical Learning: Using the if...else Condition
1. Access the Program.cs file and, to use the if...else condition, change the file as follows:
using System; using System.Collections.Generic; using System.Linq;

C# 3.0 Practical Learning

228

using System.Text; namespace ElectronicStore2 { class Program { static StoreItem CreateStoreItem() { StoreItem sItem = new StoreItem(); int Category; double ItemPrice = 0D; Console.WriteLine( "To create a store item, enter its information"); Console.Write("Item Number: "); sItem.ItemNumber = long.Parse(Console.ReadLine()); Console.WriteLine("Category"); Console.WriteLine("1. Unknown/Miscellaneous"); Console.WriteLine("2. Cables and Connectors"); Console.WriteLine("3. Cell Phones and Accessories"); Console.WriteLine("4. Headphones"); Console.WriteLine("5. Digital Cameras"); Console.WriteLine("6. PDAs and Accessories"); Console.WriteLine("7. Telephones and Accessories"); Console.WriteLine("8. TVs and Videos - Plasma / LCD"); Console.WriteLine("9. Surge Protector"); Console.WriteLine( "10. Instructional and Tutorials (VHS & DVD)TVs and Console.Write("Your Choice? "); Category = int.Parse(Console.ReadLine()); if (Category == 1) sItem.Category = ItemsCategories.Unknown; if (Category == 2) sItem.Category = ItemsCategories.CablesAndConnectors; if (Category == 3) sItem.Category = ItemsCategories.CellPhonesAndAccessories; if (Category == 4) sItem.Category = ItemsCategories.Headphones; if (Category == 5) sItem.Category = ItemsCategories.DigitalCameras; if (Category == 6) sItem.Category = ItemsCategories.PDAsAndAccessories; if (Category == 7) sItem.Category = ItemsCategories.TelephonesAndAccessories; if (Category == 8) sItem.Category = ItemsCategories.TVsAndVideos; if (Category == 9) sItem.Category = ItemsCategories.SurgeProtectors; if (Category == 10) sItem.Category = ItemsCategories.Instructional; Console.Write("Make: "); sItem.Make = Console.ReadLine(); Console.Write("Model: "); sItem.Model = Console.ReadLine(); Console.Write("Unit Price: ");

Videos");

C# 3.0 Practical Learning

229

ItemPrice = double.Parse(Console.ReadLine()); if( ItemPrice <= 0 ) sItem.UnitPrice = 0.00D; else sItem.UnitPrice = ItemPrice; return sItem; } static string GetItemCategory(ItemsCategories cat) { string strCategory = "Unknown"; if (cat == ItemsCategories.CablesAndConnectors) strCategory = "Cables & Connectors"; if (cat == ItemsCategories.CellPhonesAndAccessories) strCategory = "Cell Phones & Accessories"; if (cat == ItemsCategories.Headphones) strCategory = "Headphones"; if (cat == ItemsCategories.DigitalCameras) strCategory = "Digital Cameras"; if (cat == ItemsCategories.PDAsAndAccessories) strCategory = "PDAs & Accessories"; if (cat == ItemsCategories.TelephonesAndAccessories) strCategory = "Telephones & Accessories"; if (cat == ItemsCategories.TVsAndVideos) strCategory = "TVs & Videos"; if (cat == ItemsCategories.SurgeProtectors) strCategory = "Surge Protectors"; if (cat == ItemsCategories.Instructional) strCategory = "Instructional"; return strCategory; } static void DescribeStoreItem(StoreItem item) { string strCategory = GetItemCategory(item.Category); Console.WriteLine("Store Item Description"); Console.WriteLine("Item Number: {0}", item.ItemNumber); Console.WriteLine("Category: {0}", strCategory); Console.WriteLine("Make {0}", item.Make); Console.WriteLine("Model: {0}", item.Model); Console.WriteLine("Unit Price: {0:C}", item.UnitPrice); } static void Main() { string strTitle1 = "=-= Nearson Electronics =-="; string strTitle2 = "******* Store Items ******"; Console.WriteLine(strTitle1); Console.WriteLine(strTitle2); StoreItem saleItem = CreateStoreItem(); Console.WriteLine(""); Console.WriteLine(strTitle1); Console.WriteLine(strTitle2); DescribeStoreItem(saleItem);

C# 3.0 Practical Learning

230

Console.WriteLine(""); } } }

2. Execute the application to test it. Here is an example:

=-= Nearson Electronics =-= ******* Store Items ****** To create a store item, enter its information Item Number: 937494 Category 1. Unknown/Miscellaneous 2. Cables and Connectors 3. Cell Phones and Accessories 4. Headphones 5. Digital Cameras 6. PDAs and Accessories 7. Telephones and Accessories 8. TVs and Videos - Plasma / LCD 9. Surge Protector 10. Instructional and Tutorials (VHS & DVD)TVs and Videos Your Choice? 5 Make: Canon Model: EOS 30D Unit Price: 1395.95 =-= Nearson Electronics =-= ******* Store Items ****** Store Item Description Item Number: 937494 Category: Digital Cameras Make Canon Model: EOS 30D Unit Price: $1,395.95 Press any key to continue . . .

3. Close the DOS window

Logical Conjunction: AND
C# 3.0 Practical Learning
231

Introduction
Imagine that a real estate agent who will be using your program is meeting with a potential buyer and asking questions from the following program:
using System; public enum HouseType { Unknown, SingleFamily, Townhouse, Condominium } public class Program { static int Main() { var type = HouseType.Unknown; var choice = 0; var value = 0D; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); choice = int.Parse(Console.ReadLine()); if (choice type = if (choice type = if (choice type = == 1) HouseType.SingleFamily; == 2) HouseType.Townhouse; == 3) HouseType.Condominium;

Console.Write("Up to how much can you afford? $"); value = double.Parse(Console.ReadLine()); Console.WriteLine("\nDesired House Type: Console.WriteLine("Maximum value afforded: } } return 0; {0}", type); {0:C}\n", value);

Suppose a customer responds to these questions: she indicates that she wants single family house but she cannot afford more than $550,000:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 1 Up to how much can you afford? $550000 Desired House Type: Maximum value afforded: SingleFamily $550,000.00

C# 3.0 Practical Learning

232

Press any key to continue . . .

When considering a house for this customer, there are two details to be validated here: the house must be a single family home, second, it must cost less than $550,001. We can create two statements as follows: 1. The house is single family 2. The house costs less than $550,000 From our list of real estate properties, if we find a house that is a single family home, we put it in our list of considered properties:
Type of House House

The house is single family

True

On the other hand, if we find a house that is less than or equal to $550,000, we retain it:
Price Range Value

$550,000

True

One of the ways you can combine two comparisons is by joining them. For our customer, we want a house to meet BOTH criteria. If the house is a town house, based on the request of our customer, its conditional value is false. If the house is more than $550,000, the value of the Boolean Value is true. The Boolean operator used to join two criteria is called AND. This can be illustrated as follows:
Type of House House Value Result

Town House

$625,000

Town House AND $625,000 False

False

False

In C#, the Boolean AND operator is performed using the && operator. Here is an example:
using System; public enum HouseType { Unknown, SingleFamily,

C# 3.0 Practical Learning

233

}

Townhouse, Condominium

public class Exercise { static int Main() { var type = HouseType.Unknown; var choice = 0; var value = 0D; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); choice = int.Parse(Console.ReadLine()); Console.Write("Up to how much can you afford? $"); value = double.Parse(Console.ReadLine()); if(choice == 1) type = HouseType.SingleFamily; if (choice == 2) type = HouseType.Townhouse; if (choice == 3) type = HouseType.Condominium; Console.WriteLine("\nDesired House Type: Console.WriteLine("Maximum value afforded:

{0}", type); {0:C}", value);

if (type == HouseType.SingleFamily && value <= 550000) Console.WriteLine("\nDesired House Matched"); return 0; } }

Here is an example of running the program:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 1 Up to how much can you afford? $450000 Desired House Type: Maximum value afforded: SingleFamily $450,000.00

Desired House Matched Press any key to continue . . .

By definition, a logical conjunction combines two conditions. To make the program easier to read, each side of the conditions can be included in parentheses. Here is an example:
using System; public enum HouseType

C# 3.0 Practical Learning

234

{ Unknown, SingleFamily, Townhouse, Condominium } public class Exercise { static int Main() { var type = HouseType.Unknown; var choice = 0; var value = 0D; . . . if( (type == HouseType.SingleFamily) && (value <= 550000) ) Console.WriteLine("\nDesired House Matched"); return 0;

} }

Suppose we find a single family home. The first condition is true for our customer. With the AND Boolean operator, if the first condition is true, then we consider the second criterion. Suppose that the house we are considering costs $750,500: the price is out of the customer's range. Therefore, the second condition is false. In the AND Boolean algebra, if the second condition is false, even if the first is true, the whole condition is false. This would produce the following table:
Type of House House Value Result

Single Family True

$750,500 False

Single Family AND $750,500 False

This can be illustrated by the following run of the program:
using System; public enum HouseType { Unknown, SingleFamily, Townhouse, Condominium } class Program { static void Main() { var type = HouseType.Unknown; int choice;

C# 3.0 Practical Learning

235

var value = 0M; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); choice = int.Parse(Console.ReadLine()); if (choice type = if (choice type = if (choice type = == 1) HouseType.SingleFamily; == 2) HouseType.Townhouse; == 3) HouseType.Condominium;

Console.Write("Up to how much can you afford? $"); value = decimal.Parse(Console.ReadLine()); Console.WriteLine("\nDesired House Type: Console.WriteLine("Maximum value afforded: {0}", type); {0:C}", value);

if (type == HouseType.SingleFamily && value <= 550000) Console.WriteLine("\nDesired House Matched"); else Console.WriteLine("\nThe House Doesn't Match the Desired Criteria"); } }

Here is an example of running the program:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 1 Up to how much can you afford? $750000 Desired House Type: Maximum value afforded: SingleFamily $750,000.00

The House Doesn't Match the Desired Criteria Press any key to continue . . .

Suppose we find a townhouse that costs $420,000. Although the second condition is true, the first is false. In Boolean algebra, an AND operation is false if either condition is false:
Type of House House Value Result

Town House False

$420,000 True

Town House AND $420,000 False
236

C# 3.0 Practical Learning

Here is an example of running the above program:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 2 Up to how much can you afford? $420000 Desired House Type: Maximum value afforded: Townhouse $420,000.00

The House Doesn't Match the Desired Criteria Press any key to continue . . .

If we find a single family home that costs $345,000, both conditions are true. In Boolean algebra, an AND operation is true if BOTH conditions are true. This can be illustrated as follows:
Type of House House Value Result

Single Family True

$345,000 True

Single Family AND $345,000 True

This can be revealed in the following run of the above program:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 1 Up to how much can you afford? $345000 Desired House Type: Maximum value afforded: SingleFamily $345,000.00

Desired House Matched Press any key to continue . . .

These four tables can be resumed as follows:
If Condition1 If Condition2 is is Condition1 AND Condition2

False False True

False True False C# 3.0 Practical Learning

False False False
237

True

True

True

As you can see, a logical conjunction is true only of BOTH conditions are true.

Combining Conjunctions
As seen above, the logical conjunction operator is used to combine two conditions. In some cases, you will need to combine more than two conditions. Imagine a customer wants to purchase a single family house that costs up to $450,000 with an indoor garage. This means that the house must fulfill these three requirements: A. The house is a single family home B. The house costs less than $450,001 C. The house has an indoor garage Here the program that could be used to check these conditions:
using System; public enum HouseType { Unknown, SingleFamily, Townhouse, Condominium } public class Exercise { static int Main() { var type = HouseType.Unknown; var choice = 0; var value = 0D; var hasIndoorGarage = false; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); choice = int.Parse(Console.ReadLine()); if (choice type = if (choice type = if (choice type = == 1) HouseType.SingleFamily; == 2) HouseType.Townhouse; == 3) HouseType.Condominium;

Console.Write("Up to how much can you afford? $"); value = double.Parse(Console.ReadLine());

C# 3.0 Practical Learning

238

");

Console.Write("Does the house have an indoor garage (1=Yes/0=No)? int ans = int.Parse(Console.ReadLine()); Console.WriteLine("\nDesired House Type: {0}", type); Console.WriteLine("Maximum value afforded: {0:C}", value); Console.Write("House has indoor garage: "); if (ans == 1) Console.WriteLine("Yes"); else Console.WriteLine("No");

== 1))

if ((type == HouseType.SingleFamily) && (value <= 550000) && (ans else Console.WriteLine("\nDesired House Matched"); Console.WriteLine("\nThe House Doesn't Match the Desired

Criteria"); }

return 0; }

We saw that when two conditions are combined, the compiler first checks the first condition, followed by the second. In the same way, if three conditions need to be considered, the compiler evaluates the truthfulness of the first condition:
Type of House A

Town House False If the first condition (or any condition) is false, the whole condition is false, regardless of the outcome of the other(s). If the first condition is true, then the second condition is evaluated for its truthfulness:
Type of House A Property Value B

Single Family True

$655,000 False

C# 3.0 Practical Learning

239

If the second condition is false, the whole combination is considered false:
A B A && B

True

False

False

When evaluating three conditions, if either the first or the second is false, since the whole condition would become false, there is no reason to evaluate the third. If both the first and the second conditions are false, there is also no reason to evaluate the third condition. Only if the first two conditions are true will the third condition be evaluated whether it is true:
Type of House A Property Value B Indoor Garage C

Single Family True

$425,650 True

None False

The combination of these conditions in a logical conjunction can be written as A && B && C. If the third condition is false, the whole combination is considered false:
A B A && B C A && B && C

True

True

True

False

False

To verify this, here is an example of running the program:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 1 Up to how much can you afford? $425000 Does the house have an indoor garage (1=Yes/0=No)? 0 Desired House Type: SingleFamily Maximum value afforded: $425,000.00 House has indoor garage: No The House Doesn't Match the Desired Criteria Press any key to continue . . .

From our discussion so far, the truth table of the combinations can be illustrated as follows: C# 3.0 Practical Learning
240

A

B

C

A && B && C

False True True

Don't Care False True

Don't Care Don't Care False

False False False

The whole combination is true only if all three conditions are true. This can be illustrated as follows:
A B C A && B && C

False False True True False False True True

False False False False True True True True

False True False True False True False True

False False False False False False False True

Logical Disjunction: OR
Introduction
Our real estate company has single family homes, townhouses, and condominiums. All of the condos have only one level, also referred to as a story. Some of the single family homes have one story, some have two and some others have three levels. All townhouses have three levels. Another customer wants to buy a home. The customer says that he primarily wants a condo, but if our real estate company doesn't have a condominium, that is, if the company has only houses, whatever it is, whether a house or a condo, it must have only one level (story) (due to an illness, the customer would not climb the stairs). When considering the properties of our company, we would proceed with these statements: 1. The property is a condominium 2. The property has one story If we find a condo, since all of our condos have only one level, the criterion set by the customer is true. Even if we were considering another (type of) property, it wouldn't matter. This can be resumed in the following table: C# 3.0 Practical Learning
241

Type of House

House

Condominium

True

The other properties would not be considered, especially if they have more than one story:
Number of Stories Value

3

False

To check for either of two conditions, in Boolean algebra, you can use an operator called OR. We can show this operation as follows:
Condominium One Story Condominium OR 1 Story

True

False

True

In Boolean algebra, this type of comparison is performed using the OR operator. In C#, the OR operator is performed using the || operator. Here is an example:
using System; public enum HouseType { Unknown, SingleFamily, Townhouse, Condominium } public class Exercise { static int Main() { var type = HouseType.Unknown; var choice = 0; var stories = 1; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); choice = int.Parse(Console.ReadLine()); if (choice type = if (choice type = if (choice type = == 1) HouseType.SingleFamily; == 2) HouseType.Townhouse; == 3) HouseType.Condominium;

C# 3.0 Practical Learning

242

Console.Write("How many stories? "); stories = int.Parse(Console.ReadLine()); Console.WriteLine("\nDesired House Type: {0}", type); Console.WriteLine("Number of Stories: {0}", stories); if ((type == HouseType.Condominium) || (stories == 1)) Console.WriteLine("\nDesired House Matched"); else Console.WriteLine("\nThe House Doesn't Match the Desired Criteria"); } } return 0;

Here is an example of running the program:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 3 How many stories? 6 Desired House Type: Condominium Number of Stories: 6 Desired House Matched Press any key to continue . . .

Suppose that, among the properties our real estate company has available, there is no condominium. In this case, we would then consider the other properties:
Type of House House

Single Family

False

If we have a few single family homes, we would look for one that has only one story. Once we find one, our second criterion becomes true:
Type of House One Story Condominium OR 1 Story

False

True

True

This can be illustrated in the following run of the above program:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 1

C# 3.0 Practical Learning

243

How many stories? 1 Desired House Type: SingleFamily Number of Stories: 1 Desired House Matched Press any key to continue . . .

If we find a condo and it is one story, both criteria are true. This can be illustrated in the following table:
Type of House One Story Condominium OR 1 Story

False True

True True

True True

The following run of the program demonstrates this:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 3 How many stories? 1 Desired House Type: Condominium Number of Stories: 1 Desired House Matched Press any key to continue . . .

A Boolean OR operation produces a false result only if BOTH conditions ARE FALSE:
If Condition1 If Condition2 Condition1 OR Condition2 is is

False True True False

True False True False

True True True False

Here is another example of running the program:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 2 How many stories? 2 Desired House Type: Townhouse

C# 3.0 Practical Learning

244

Number of Stories:

2

The House Doesn't Match the Desired Criteria Press any key to continue . . .

Combinations of Disjunctions
As opposed to evaluating only two conditions, you may face a situation that presents three of them and must consider a combination of more than two conditions.

C# 3.0 Practical Learning

245

CONDITIONAL SWITCHES
if Switches
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; public class Exercise { static int Main() { var Number1 = 0; var Number2 = 0; var Maximum = 0; var Num1 = ""; var 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); Console.WriteLine(); return 0;

C# 3.0 Practical Learning

246

} }

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: Introducing Conditional Switches
1. Start Microsoft Visual C# 2. Create a new Console Application named FlowerShop2 3. To create a new class, on the main menu, click Project -> Add Class... 4. Set the Name of the class to Flower and click Add 5. Complete the Flower.cs file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace FlowerShop2 { public enum FlowerType { Roses = 1, Lilies, Daisies, Carnations, LivePlant, Mixed } public enum FlowerColor { Red = 1, White, Yellow, Pink, Orange, Blue, Lavender, Mixed } public enum FlowerArrangement { Bouquet = 1, Vase, Basket, Any }

C# 3.0 Practical Learning

247

public class Flower { public FlowerType Type; public FlowerColor Color; public FlowerArrangement Arrangement; public decimal UnitPrice; public Flower() { Type = FlowerType.Mixed; Color = FlowerColor.Mixed; Arrangement = FlowerArrangement.Vase; UnitPrice = 0.00M; } public Flower(FlowerType type) { Type = type; Color = FlowerColor.Mixed; Arrangement = FlowerArrangement.Vase; UnitPrice = 0.00M; } public Flower(FlowerType type, FlowerColor color, FlowerArrangement argn, decimal price) { Type = type; Color = color; Arrangement = argn; UnitPrice = price; }

} }

6. Save the file

if…else if and if…else if…else
If you use an if...else conditional statement, you can process only two statements. In some cases, you may deal with more than two conditions. In this case, you can use an if...else if condition. Its formula is:
if(Condition1) Statement1; else if(Condition2) Statement2;

The compiler would first check Condition1. If Condition1 is true, then Statement1 would be executed. If Condition1 is false, then the compiler would check Condition2. If Condition2 is true, then the compiler would execute Statement2. Any other result would be ignored. Here is an example:
using System; public enum HouseType { Unknown,

C# 3.0 Practical Learning

248

SingleFamily, Townhouse,

Condominium
} public class Exercise { static int Main() { var Type = HouseType.Unknown; var Choice = 0; var Garage = ""; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); Choice = int.Parse(Console.ReadLine()); if (Choice == 1) Type = HouseType.SingleFamily; else if (Choice == 2) Type = HouseType.Townhouse; "); Console.Write("Does the house have an indoor garage (1=Yes/0=No)? var Answer if (Answer Garage else Garage = int.Parse(Console.ReadLine()); == 1) = "Yes"; = "No";

} }

Console.WriteLine("\nDesired House Type: {0}", Type); Console.WriteLine("Has indoor garage? {0}", Garage); return 0;

Here is an example of running the program:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 1 Does the house have an indoor garage (1=Yes/0=No)? 1 Desired House Type: SingleFamily Has indoor garage? Yes Press any key to continue . . .

Here is another example of running the program:
Enter the type of house you want to purchase 1. Single Family

C# 3.0 Practical Learning

249

2. Townhouse 3. Condominium You Choice? 2 Does the house have an indoor garage (1=Yes/0=No)? 6 Desired House Type: Townhouse Has indoor garage? No Press any key to continue . . .

Notice that only two conditions are evaluated. Any condition other than these two is not considered. Because there can be other alternatives, the C# language provides an alternate else as the last resort. Its formula is:
if(Condition1) Statement1; else if(Condition2) Statement2; else Statement-n; if(Condition1) Statement1; else if(Condition2) Statement2; else if(Condition3) Statement3; else Statement-n;

The compiler will check the first condition. If Condition1 is true, it executes Statement1. If Condition1 is false, then the compiler will check the second condition. If Condition2 is true, it will execute Statement2. When the compiler finds a Condition-n to be true, it will execute its corresponding statement. It that Condition-n is false, the compiler will check the subsequent condition. This means you can include as many conditions as you see fit using the else if statement. If after examining all the known possible conditions you still think that there might be an unexpected condition, you can use the optional single else. Here is an example:
using System; public enum HouseType { Unknown, SingleFamily, Townhouse, Condominium } public class Exercise { public static int Main() { var Type = HouseType.Unknown; var Choice = 0; var Garage = ""; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); Choice = int.Parse(Console.ReadLine()); if (Choice == 1)

C# 3.0 Practical Learning

250

Type = HouseType.SingleFamily; else if (Choice == 2) Type = HouseType.Townhouse; else if (Choice == 3) Type = HouseType.Condominium; else Type = HouseType.Unknown; Console.Write("Does the house have an indoor garage (1=Yes/0=No)? "); var Answer if (Answer Garage else Garage = int.Parse(Console.ReadLine()); == 1) = "Yes"; = "No";

Console.WriteLine("\nDesired House Type: {0}", Type); Console.WriteLine("Has indoor garage? {0}", Garage); } } return 0;

Here is an example of running the program:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 3 Does the house have an indoor garage (1=Yes/0=No)? 0 Desired House Type: Condominium Has indoor garage? No Press any key to continue . . .

Case Switches
Introduction
When defining an expression whose result would lead to a specific program execution, the switch statement considers that result and executes a statement based on the possible outcome of that expression, this possible outcome is called a case. The different outcomes are listed in the body of the switch statement and each case has its own execution, if necessary. The body of a switch statement is delimited from an opening to a closing curly brackets: “{“ to “}”. The syntax of the switch statement is:
switch(Expression) { case Choice1: Statement1; break; case Choice2: Statement2; break;

C# 3.0 Practical Learning

251

case Choice-n: Statement-n; break; }

In C++, you can omit the break keyword in a case. This creates the "fall through" effect as follows: after code executes in a case, if nothing "stops" it, the execution continues to the next case. This has caused problems and confusing execution in the past in some C++ programs. To avoid it, C# requires code interruption at the end of every case. This interruption is done using the break keyword. The expression to examine in a case statement is an integer. Since a member of an enumerator (enum) and the character (char) data types are just other forms of integers, they can be used too. Here is an example of using the switch statement:
using System; public enum HouseType { Unknown, SingleFamily, Townhouse, Condominium } public class Exercise { public static int Main() { var Type = HouseType.Unknown; var Choice = 0; var Garage = ""; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); Choice = int.Parse(Console.ReadLine()); switch (Choice) { case 1: Type = HouseType.SingleFamily; break; case 2: Type = HouseType.Townhouse; break; case 3: Type = HouseType.Condominium; break; }

C# 3.0 Practical Learning

252

Console.Write("Does the house have an indoor garage (1=Yes/0=No)? "); var Answer if (Answer Garage else Garage = int.Parse(Console.ReadLine()); == 1) = "Yes"; = "No";

Console.WriteLine("\nDesired House Type: {0}", Type); Console.WriteLine("Has indoor garage? {0}", Garage); } } return 0;

When establishing the possible outcomes that the switch statement should consider, at times there will be possibilities other than those listed and you will be likely to consider them. This special case is handled by the default keyword. The default case would be considered if none of the listed cases matches the supplied answer. The syntax of the switch statement that considers the default case would be:
switch(Expression) { case Choice1: Statement1; break; case Choice2: Statement2; break; case Choice-n: Statement-n; break; default: Other-Possibility; break; }

In C++, the default section doesn't need a break keyword because it is the last. In C#, every case and the default section must have its own exit mechanism, which is taken care of by a break keyword. Therefore another version of the program above would be
using System; public enum HouseType { Unknown, SingleFamily, Townhouse, Condominium } public class Exercise { public static int Main() {

C# 3.0 Practical Learning

253

var Type = HouseType.Unknown; var Choice = 0; var Garage = ""; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); Choice = int.Parse(Console.ReadLine()); switch (Choice) { case 1: Type = HouseType.SingleFamily; break; case 2: Type = HouseType.Townhouse; break; case 3: Type = HouseType.Condominium; break; default: Type = HouseType.Unknown; break; } "); Console.Write("Does the house have an indoor garage (1=Yes/0=No)? var Answer if (Answer Garage else Garage = int.Parse(Console.ReadLine()); == 1) = "Yes"; = "No";

Console.WriteLine("\nDesired House Type: {0}", Type); Console.WriteLine("Has indoor garage? {0}", Garage); return 0; } }

Here is an example of running the program:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 8 Does the house have an indoor garage (1=Yes/0=No)? 2 Desired House Type: Unknown Has indoor garage? No Press any key to continue . . .

C# 3.0 Practical Learning

254

Besides a value of an int type, you can also use another variant of integers on a switch statement. For example, you can use letters to validate the cases. Here is an example:
using System; public enum HouseType { Unknown, SingleFamily, Townhouse, Condominium } public class Exercise { public static int Main() { var Type = HouseType.Unknown; var Choice = 0; var Garage = ""; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); Choice = int.Parse(Console.ReadLine()); switch (Choice) { case 1: Type = HouseType.SingleFamily; break; case 2: Type = HouseType.Townhouse; break; case 3: Type = HouseType.Condominium; break; default: Type = HouseType.Unknown; break; } Console.Write("Does the house have an indoor garage (y/n)? "); var Answer = char.Parse(Console.ReadLine()); switch (Answer) { case 'y': Garage = "Yes"; break; case 'Y': Garage = "Yes";

C# 3.0 Practical Learning

255

break; case 'n': Garage = "No"; break; case 'N': Garage = "No"; break; default: Garage = "Not Specified"; break; } Console.WriteLine("\nDesired House Type: {0}", Type); Console.WriteLine("Has indoor garage? {0}", Garage); return 0; } }

Here is an example of running the program:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 3 Does the house have an indoor garage (y/n)? y Desired House Type: Condominium Has indoor garage? Yes Press any key to continue . . .

Practical Learning: Using Conditional Switches
1. To create a new class, in the Solution Explorer, right-click the project name, position the mouse on Add and click Class... 2. Set the Name of the class to OrderProcessing and click Add 3. Complete the OrderProcessing.cs file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace FlowerShop2 { class OrderProcessing { public Flower FlowerOrder; public int Quantity; public OrderProcessing() {

C# 3.0 Practical Learning

256

FlowerOrder = new Flower(); } public decimal GetTotalPrice() { return Quantity * FlowerOrder.UnitPrice; } public void GetFlowerType() { int choice = 0; Console.WriteLine("Enter the Type of Flower Order"); Console.WriteLine("1. Roses"); Console.WriteLine("2. Lilies"); Console.WriteLine("3. Daisies"); Console.WriteLine("4. Carnations"); Console.WriteLine("5. Live Plant"); Console.WriteLine("6. Mixed"); Console.Write("Your Choice: "); choice = int.Parse(Console.ReadLine()); switch (choice) { case 1: FlowerOrder.Type break; case 2: FlowerOrder.Type break; case 3: FlowerOrder.Type break; case 4: FlowerOrder.Type break; case 5: FlowerOrder.Type break; default: FlowerOrder.Type break; } } public void GetFlowerColor() { int choice = 0; Console.WriteLine("Enter the Color"); Console.WriteLine("1. Red"); Console.WriteLine("2. White"); Console.WriteLine("3. Yellow"); Console.WriteLine("4. Pink"); Console.WriteLine("5. Orange"); Console.WriteLine("6. Blue"); Console.WriteLine("7. Lavender"); Console.WriteLine("8. Mixed"); Console.Write("Your Choice: "); choice = int.Parse(Console.ReadLine());

= FlowerType.Roses; = FlowerType.Lilies; = FlowerType.Daisies; = FlowerType.Carnations; = FlowerType.LivePlant; = FlowerType.Mixed;

C# 3.0 Practical Learning

257

}

switch (choice) { case 1: FlowerOrder.Color break; case 2: FlowerOrder.Color break; case 3: FlowerOrder.Color break; case 4: FlowerOrder.Color break; case 5: FlowerOrder.Color break; case 6: FlowerOrder.Color break; case 7: FlowerOrder.Color break; default: FlowerOrder.Color break; }

= FlowerColor.Red; = FlowerColor.White; = FlowerColor.Yellow; = FlowerColor.Pink; = FlowerColor.Yellow; = FlowerColor.Blue; = FlowerColor.Lavender; = FlowerColor.Mixed;

public void GetFlowerArrangement() { int choice = 0; Console.WriteLine("Enter the Type of Arrangement"); Console.WriteLine("1. Bouquet"); Console.WriteLine("2. Vase"); Console.WriteLine("3. Basket"); Console.WriteLine("4. Mixed"); Console.Write("Your Choice: "); choice = int.Parse(Console.ReadLine()); switch (choice) { case 1: FlowerOrder.Arrangement break; case 2: FlowerOrder.Arrangement break; case 3: FlowerOrder.Arrangement break; default: FlowerOrder.Arrangement break; } } public void ProcessOrder()

= FlowerArrangement.Bouquet; = FlowerArrangement.Vase; = FlowerArrangement.Basket; = FlowerArrangement.Any;

C# 3.0 Practical Learning

258

{ GetFlowerType(); GetFlowerColor(); GetFlowerArrangement(); Console.Write("Enter the Unit Price: "); FlowerOrder.UnitPrice = decimal.Parse(Console.ReadLine()); Console.Write("Enter Quantity: "); Quantity = int.Parse(Console.ReadLine());

}

public void ShowOrder() { Console.WriteLine("======================="); Console.WriteLine("==-=-=Flower Shop=-=-=="); Console.WriteLine("-----------------------"); Console.WriteLine("Flower Type: {0}", FlowerOrder.Type); Console.WriteLine("Flower Color: {0}", FlowerOrder.Color); Console.WriteLine("Arrangement: {0}", FlowerOrder.Arrangement); Console.WriteLine("Price: {0:C}", FlowerOrder.UnitPrice); Console.WriteLine("Quantity: {0}", Quantity); Console.WriteLine("Total Price: {0:C}", GetTotalPrice()); Console.WriteLine("======================="); } } }

4. Access the Program.cs file and complete it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace FlowerShop2 { class Program { static void Main() { OrderProcessing order = new OrderProcessing(); order.ProcessOrder(); Console.WriteLine(); order.ShowOrder(); Console.WriteLine(); } } }

5. Execute the application and test it. Here is an example:
Enter the Type of Flower Order 1. Roses

C# 3.0 Practical Learning

259

2. Lilies 3. Daisies 4. Carnations 5. Live Plant 6. Mixed Your Choice: 4 Enter the Color 1. Red 2. White 3. Yellow 4. Pink 5. Orange 6. Blue 7. Lavender 8. Mixed Your Choice: 7 Enter the Type of Arrangement 1. Bouquet 2. Vase 3. Basket 4. Mixed Your Choice: 3 Enter the Unit Price: 45.85 Enter Quantity: 3 ======================= ==-=-=Flower Shop=-=-== ----------------------Flower Type: Carnations Flower Color: Lavender Arrangement: Basket Price: $45.85 Quantity: 3 Total Price: $137.55 ======================= Press any key to continue . . .

6. Close the DOS window

Combining Cases
Each of the cases we have used so far examined only one possibility before executing the corresponding statement. You can combine cases to execute the same statement. To do this, type a case, its value, and the semi-colon. Type another case using the same formula. When the cases are ready, you can then execute the desired statement. Here is an example:
using System; public enum HouseType { Unknown, SingleFamily, Townhouse, Condominium }

C# 3.0 Practical Learning

260

public class Exercise { public static int Main() { var Type = HouseType.Unknown; var Choice = 0; var Garage = ""; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); Choice = int.Parse(Console.ReadLine()); switch (Choice) { case 1: Type = HouseType.SingleFamily; break; case 2: Type = HouseType.Townhouse; break; case 3: Type = HouseType.Condominium; break; default: Type = HouseType.Unknown; break; } Console.Write("Does the house have an indoor garage (y/n)? "); var Answer = char.Parse(Console.ReadLine()); switch (Answer) { case 'y': case 'Y': Garage = "Yes"; break; case 'n': case 'N': Garage = "No"; break; default: Garage = "Not Specified"; break;

}

Console.WriteLine("\nDesired House Type: {0}", Type); Console.WriteLine("Has indoor garage? {0}", Garage); } } return 0;

C# 3.0 Practical Learning

261

This would produce:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 3 Does the house have an indoor garage (y/n)? Y Desired House Type: Condominium Has indoor garage? Yes Press any key to continue . . .

Using Enumerations
One of the most fundamental uses of enumerations is to process them in a switch statement. To do this, you pass the value of an enumeration to a switch. The values of the enumerations are then processed in the case statements. Here is an example:
using System; public enum HouseType { Unknown, SingleFamily, Townhouse, Condominium } public class Exercise { public static int Main() { var PropertyType = ""; var Choice = 0; var Garage = ""; Console.WriteLine("Enter the type of house you want to purchase"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.Write("You Choice? "); Choice = int.Parse(Console.ReadLine()); switch ((HouseType)Choice) { case HouseType.SingleFamily: PropertyType = "Single Family"; break; case HouseType.Townhouse: PropertyType = "Townhouse"; break; case HouseType.Condominium: PropertyType = "Condominium";

C# 3.0 Practical Learning

262

break; default: PropertyType = "Unknown"; break; } Console.Write("Does the house have an indoor garage (y/n)? "); var Answer = char.Parse(Console.ReadLine()); switch (Answer) { case 'y': case 'Y': Garage = "Yes"; break; case 'n': case 'N': Garage = "No"; break; default: Garage = "Not Specified"; break;

}

Console.WriteLine("\nDesired House Type: {0}", PropertyType); Console.WriteLine("Has indoor garage? {0}", Garage); } } return 0;

Here is an example of running the program:
Enter the type of house you want to purchase 1. Single Family 2. Townhouse 3. Condominium You Choice? 1 Does the house have an indoor garage (y/n)? N Desired House Type: Single Family Has indoor garage? No Press any key to continue . . .

C# 3.0 Practical Learning

263

COUNTING AND LOOPING
Conditional Looping

Introduction
A loop is a type of conditional statement that keeps checking a condition and executing a statement until the condition is false.

while a Condition is True
One of the operators used to perform a loop is called while. Its formula is:
while(Condition) Statement;

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:
using System; public class Exercise

C# 3.0 Practical Learning

264

{ public static int Main() { var Stories = 0; while( Stories <= 4 ) { Console.WriteLine("Number {0}", Stories); Stories++; } Console.WriteLine(); return 0; } }

This would produce:
Number Number Number Number Number 0 1 2 3 4

Press any key to continue . . .

To effectively execute a while condition, you should make sure you provide a mechanism for the compiler to use or 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:

do This while a Condition is True
The while loop is used first check a condition and then execute a statement. If the condition is false, the statement would never execute. Consider the following program: 265 C# 3.0 Practical Learning

using System; public class Exercise { public static int Main() { var Stories = 5; while (Stories <= 4) { Console.WriteLine("Number {0}", Stories); Stories++; } Console.WriteLine(); return 0;

} }

When this program executes, nothing from the while loop would execute because, as the condition is checked in the beginning, it is false and the compiler would not get to the Statement. In some cases, you may want to execute a statement before checking the condition for the first time. This can be done using the do…while statement. Its formula is:
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.

Another version of the counting program seen previously would be:
using System;

C# 3.0 Practical Learning

266

public class Exercise { public static int Main() { var Stories = 0; do Console.WriteLine("Number {0}", Stories++); while (Stories <= 4); Console.WriteLine(); return 0;

} }

This would produce:
Number Number Number Number Number 0 1 2 3 4

Press any key to continue . . .

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 "}".

Practical Learning: Introducing Counting and Looping
1. Start Microsoft Visual C# 2. Create a new Console Application named FlowerShop3 3. To create a new class, in the Class View, right-click the project name -> Add -> Class... 4. Set the Name of the class to Flower and click Add 5. Complete the Flower.cs file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace FlowerShop3 { public enum FlowerType { Roses = 1, Lilies, Daisies, Carnations, LivePlant, Mixed }

C# 3.0 Practical Learning

267

public enum FlowerColor { Red = 1, White, Yellow, Pink, Orange, Blue, Lavender, Mixed } public enum FlowerArrangement { Bouquet = 1, Vase, Basket, Any } class Flower { public FlowerType Type; public FlowerColor Color; public FlowerArrangement Arrangement; public decimal UnitPrice; public Flower() { Type = FlowerType.Mixed; Color = FlowerColor.Mixed; Arrangement = FlowerArrangement.Vase; UnitPrice = 0.00M; } public Flower(FlowerType type) { Type = type; Color = FlowerColor.Mixed; Arrangement = FlowerArrangement.Vase; UnitPrice = 0.00M; } public Flower(FlowerType type, FlowerColor color, FlowerArrangement argn, decimal price) { Type = type; Color = color; Arrangement = argn; UnitPrice = price; } } }

6. To create a new class, in the Solution Explorer, right-click the project name, position the mouse on Add and click Class... 7. Set the Name of the class to OrderProcessing and click Add 8. Complete the OrderProcessing.cs file as follows: C# 3.0 Practical Learning
268

using using using using

System; System.Collections.Generic; System.Linq; System.Text;

namespace FlowerShop3 { class OrderProcessing { public Flower FlowerOrder; public int Quantity; public OrderProcessing() { FlowerOrder = new Flower(); } public decimal GetTotalPrice() { return Quantity * FlowerOrder.UnitPrice; } public void GetFlowerType() { int choice = 0; do {

Console.WriteLine("Enter the Type of Flower Order"); Console.WriteLine("1. Roses"); Console.WriteLine("2. Lilies"); Console.WriteLine("3. Daisies"); Console.WriteLine("4. Carnations"); Console.WriteLine("5. Live Plant"); Console.WriteLine("6. Mixed"); Console.Write("Your Choice: "); choice = int.Parse(Console.ReadLine()); } while ((choice < 1) || (choice > 6)); switch (choice) { case 1: FlowerOrder.Type break; case 2: FlowerOrder.Type break; case 3: FlowerOrder.Type break; case 4: FlowerOrder.Type break; case 5: FlowerOrder.Type break; default: FlowerOrder.Type break; }

= FlowerType.Roses; = FlowerType.Lilies; = FlowerType.Daisies; = FlowerType.Carnations; = FlowerType.LivePlant; = FlowerType.Mixed;

C# 3.0 Practical Learning

269

} public void GetFlowerColor() { int choice = 0; do {

Console.WriteLine("Enter the Color"); Console.WriteLine("1. Red"); Console.WriteLine("2. White"); Console.WriteLine("3. Yellow"); Console.WriteLine("4. Pink"); Console.WriteLine("5. Orange"); Console.WriteLine("6. Blue"); Console.WriteLine("7. Lavender"); Console.WriteLine("8. Mixed"); Console.Write("Your Choice: "); choice = int.Parse(Console.ReadLine()); } while ((choice < 1) || (choice > 8)); switch (choice) { case 1: FlowerOrder.Color break; case 2: FlowerOrder.Color break; case 3: FlowerOrder.Color break; case 4: FlowerOrder.Color break; case 5: FlowerOrder.Color break; case 6: FlowerOrder.Color break; case 7: FlowerOrder.Color break; default: FlowerOrder.Color break; }

= FlowerColor.Red; = FlowerColor.White; = FlowerColor.Yellow; = FlowerColor.Pink; = FlowerColor.Yellow; = FlowerColor.Blue; = FlowerColor.Lavender; = FlowerColor.Mixed;

}

public void GetFlowerArrangement() { int choice = 0; do {

Console.WriteLine("Enter the Type of Arrangement"); Console.WriteLine("1. Bouquet"); Console.WriteLine("2. Vase"); Console.WriteLine("3. Basket");

C# 3.0 Practical Learning

270

Console.WriteLine("4. Mixed"); Console.Write("Your Choice: "); choice = int.Parse(Console.ReadLine()); } while ((choice < 1) || (choice > 4)); switch (choice) { case 1: FlowerOrder.Arrangement break; case 2: FlowerOrder.Arrangement break; case 3: FlowerOrder.Arrangement break; default: FlowerOrder.Arrangement break; }

= FlowerArrangement.Bouquet; = FlowerArrangement.Vase; = FlowerArrangement.Basket; = FlowerArrangement.Any;

}

public void ProcessOrder() { GetFlowerType(); GetFlowerColor(); GetFlowerArrangement(); Console.Write("Enter the Unit Price: "); FlowerOrder.UnitPrice = decimal.Parse(Console.ReadLine()); Console.Write("Enter Quantity: "); Quantity = int.Parse(Console.ReadLine()); } public void ShowOrder() { Console.WriteLine("======================="); Console.WriteLine("==-=-=Flower Shop=-=-=="); Console.WriteLine("-----------------------"); Console.WriteLine("Flower Type: {0}", FlowerOrder.Type); Console.WriteLine("Flower Color: {0}", FlowerOrder.Color); Console.WriteLine("Arrangement: {0}", FlowerOrder.Arrangement); Console.WriteLine("Price: {0:C}", FlowerOrder.UnitPrice); Console.WriteLine("Quantity: {0}", Quantity); Console.WriteLine("Total Price: {0:C}", GetTotalPrice()); Console.WriteLine("======================="); } } }

9. Access the Program.cs file and complete it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

C# 3.0 Practical Learning

271

namespace FlowerShop3 { class Program { static void Main() { OrderProcessing order = new OrderProcessing(); order.ProcessOrder(); Console.WriteLine(); order.ShowOrder(); Console.WriteLine();

} } }

10.

Execute the application and test it. Here is an example:

Enter the Type of Flower Order 1. Roses 2. Lilies 3. Daisies 4. Carnations 5. Live Plant 6. Mixed Your Choice: 8 Enter the Type of Flower Order 1. Roses 2. Lilies 3. Daisies 4. Carnations 5. Live Plant 6. Mixed Your Choice: 2 Enter the Color 1. Red 2. White 3. Yellow 4. Pink 5. Orange 6. Blue 7. Lavender 8. Mixed Your Choice: 9 Enter the Color 1. Red 2. White 3. Yellow 4. Pink 5. Orange 6. Blue 7. Lavender 8. Mixed Your Choice: 0 Enter the Color 1. Red 2. White

C# 3.0 Practical Learning

272

3. Yellow 4. Pink 5. Orange 6. Blue 7. Lavender 8. Mixed Your Choice: 7 Enter the Type of Arrangement 1. Bouquet 2. Vase 3. Basket 4. Mixed Your Choice: 8 Enter the Type of Arrangement 1. Bouquet 2. Vase 3. Basket 4. Mixed Your Choice: 5 Enter the Type of Arrangement 1. Bouquet 2. Vase 3. Basket 4. Mixed Your Choice: 2 Enter the Unit Price: 42.85 Enter Quantity: 2 ======================= ==-=-=Flower Shop=-=-== ----------------------Flower Type: Lilies Flower Color: Lavender Arrangement: Vase Price: $42.85 Quantity: 2 Total Price: $85.70 ======================= Press any key to continue . . .

11.

Close the DOS window

for
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; this means the counting would continue as long as the C# 3.0 Practical Learning
273

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 would let 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; public class Exercise { public static int Main() { for (var Stories = 0; Stories <= 4; Stories++) Console.WriteLine("Number {0}", Stories); Console.WriteLine(); return 0;

} }

This would produce:
Number Number Number Number 1 2 3 4

Press any key to continue . . .

Controlling the Conditional Statements
Nesting a Conditional Statement
Consider the following program:
using System; public class Exercise { public static int Main() { var TypeOfHome = 0; do { Purchase?");

Console.WriteLine("What Type of House Would you Like to Console.WriteLine("1 - Single Family"); Console.WriteLine("2 - Town House"); Console.WriteLine("3 - Condominium");

C# 3.0 Practical Learning

274

Console.Write("Your Choice? "); TypeOfHome = int.Parse(Console.ReadLine()); } while ((TypeOfHome < 1) || (TypeOfHome > 3)); if (TypeOfHome == 1) Console.WriteLine("\nType of Home: Single Family"); else if (TypeOfHome == 2) Console.WriteLine("\nType of Home: Town House"); else if (TypeOfHome == 3) Console.WriteLine("\nType of Home: Condominium"); Console.WriteLine(); return 0; } }

This is used to request one of the numbers 1, 2, or 3 from the user. Any number below 1 or above 3 is not accepted. Here is an example of running the program:
What Type of House Would you Like to Purchase? 1 - Single Family 2 - Town House 3 - Condominium Your Choice? 8 What Type of House Would you Like to Purchase? 1 - Single Family 2 - Town House 3 - Condominium Your Choice? 6 What Type of House Would you Like to Purchase? 1 - Single Family 2 - Town House 3 - Condominium Your Choice? 3 Type of Home: Condominium Press any key to continue . . .

If the user enters an invalid value, the question is simply being asked again. It would be professional to let the user know why the request came back even though what appears as a normal number was entered. To solve this and other types of problems, you can write one conditional statement inside of another. This is referred to as nesting. To create a conditional statement inside of another, simply proceed as we have done so far to create them. Here is an example:
using System; public class Exercise { public static int Main() { var TypeOfHome = 0; do {

C# 3.0 Practical Learning

275

Console.WriteLine("What Type of House Would you Like to Purchase?"); Console.WriteLine("1 - Single Family"); Console.WriteLine("2 - Townhouse"); Console.WriteLine("3 - Condominium"); Console.Write("Your Choice? "); TypeOfHome = int.Parse(Console.ReadLine());

if ((TypeOfHome < 1) || (TypeOfHome > 3)) Console.WriteLine("Invalid Choice: Please try again"); } while ((TypeOfHome < 1) || (TypeOfHome > 3)); if (TypeOfHome == 1) Console.WriteLine("\nType of Home: Single Family"); else if (TypeOfHome == 2) Console.WriteLine("\nType of Home: Townhouse"); else if (TypeOfHome == 3) Console.WriteLine("\nType of Home: Condominium"); Console.WriteLine(); return 0; } }

Here is another example of running the program:
What Type of House Would you Like to Purchase? 1 - Single Family 2 - Town House 3 - Condominium Your Choice? 0 Invalid Choice: Please try again What Type of House Would you Like to Purchase? 1 - Single Family 2 - Town House 3 - Condominium Your Choice? 6 Invalid Choice: Please try againe What Type of House Would you Like to Purchase? 1 - Single Family 2 - Town House 3 - Condominium Your Choice? 2 Type of Home: Town House Press any key to continue . . .

Practical Learning: Nesting Conditions
1. Access the OrderProcessing.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace FlowerShop3

C# 3.0 Practical Learning

276

{ class OrderProcessing { public Flower FlowerOrder; public int Quantity; public OrderProcessing() { FlowerOrder = new Flower(); } public decimal GetTotalPrice() { return Quantity * FlowerOrder.UnitPrice; } public void GetFlowerType() { int choice = 0; do {

Console.WriteLine("Enter the Type of Flower Order"); Console.WriteLine("1. Roses"); Console.WriteLine("2. Lilies"); Console.WriteLine("3. Daisies"); Console.WriteLine("4. Carnations"); Console.WriteLine("5. Live Plant"); Console.WriteLine("6. Mixed"); Console.Write("Your Choice: "); choice = int.Parse(Console.ReadLine()); if ((choice < 1) || (choice > 6)) Console.WriteLine( "Invalid Value: Please enter a value between 1 and

6");

} while ((choice < 1) || (choice > 6)); switch (choice) { case 1: FlowerOrder.Type break; case 2: FlowerOrder.Type break; case 3: FlowerOrder.Type break; case 4: FlowerOrder.Type break; case 5: FlowerOrder.Type break; default: FlowerOrder.Type break; } }

= FlowerType.Roses; = FlowerType.Lilies; = FlowerType.Daisies; = FlowerType.Carnations; = FlowerType.LivePlant; = FlowerType.Mixed;

C# 3.0 Practical Learning

277

public void GetFlowerColor() { int choice = 0; do { Console.WriteLine("Enter the Color"); Console.WriteLine("1. Red"); Console.WriteLine("2. White"); Console.WriteLine("3. Yellow"); Console.WriteLine("4. Pink"); Console.WriteLine("5. Orange"); Console.WriteLine("6. Blue"); Console.WriteLine("7. Lavender"); Console.WriteLine("8. Mixed"); Console.Write("Your Choice: "); choice = int.Parse(Console.ReadLine()); if ((choice < 1) || (choice > 8)) Console.WriteLine( "Invalid Value: Please enter a value between 1 and } while ((choice < 1) || (choice > 8)); switch (choice) { case 1: FlowerOrder.Color break; case 2: FlowerOrder.Color break; case 3: FlowerOrder.Color break; case 4: FlowerOrder.Color break; case 5: FlowerOrder.Color break; case 6: FlowerOrder.Color break; case 7: FlowerOrder.Color break; default: FlowerOrder.Color break; }

8");

= FlowerColor.Red; = FlowerColor.White; = FlowerColor.Yellow; = FlowerColor.Pink; = FlowerColor.Yellow; = FlowerColor.Blue; = FlowerColor.Lavender; = FlowerColor.Mixed;

}

public void GetFlowerArrangement() { int choice = 0; do {

C# 3.0 Practical Learning

278

Console.WriteLine("Enter the Type of Arrangement"); Console.WriteLine("1. Bouquet"); Console.WriteLine("2. Vase"); Console.WriteLine("3. Basket"); Console.WriteLine("4. Mixed"); Console.Write("Your Choice: "); choice = int.Parse(Console.ReadLine()); if ((choice < 1) || (choice > 4)) Console.WriteLine( "Invalid Value: Please enter a value between 1 and 4"); } while ((choice < 1) || (choice > 4)); switch (choice) { case 1: FlowerOrder.Arrangement break; case 2: FlowerOrder.Arrangement break; case 3: FlowerOrder.Arrangement break; default: FlowerOrder.Arrangement break; } } public void ProcessOrder() { GetFlowerType(); GetFlowerColor(); GetFlowerArrangement(); Console.Write("Enter the Unit Price: "); FlowerOrder.UnitPrice = decimal.Parse(Console.ReadLine()); Console.Write("Enter Quantity: "); Quantity = int.Parse(Console.ReadLine());

= FlowerArrangement.Bouquet; = FlowerArrangement.Vase; = FlowerArrangement.Basket; = FlowerArrangement.Any;

}

public void ShowOrder() { Console.WriteLine("======================="); Console.WriteLine("==-=-=Flower Shop=-=-=="); Console.WriteLine("-----------------------"); Console.WriteLine("Flower Type: {0}", FlowerOrder.Type); Console.WriteLine("Flower Color: {0}", FlowerOrder.Color); Console.WriteLine("Arrangement: {0}", FlowerOrder.Arrangement); Console.WriteLine("Price: {0:C}", FlowerOrder.UnitPrice); Console.WriteLine("Quantity: {0}", Quantity); Console.WriteLine("Total Price: {0:C}", GetTotalPrice()); Console.WriteLine("======================="); } }

C# 3.0 Practical Learning

279

}

2. Execute the application and test it. Here is an example:
Enter the Type of Flower Order 1. Roses 2. Lilies 3. Daisies 4. Carnations 5. Live Plant 6. Mixed Your Choice: 8 Invalid Value: Please enter a value Enter the Type of Flower Order 1. Roses 2. Lilies 3. Daisies 4. Carnations 5. Live Plant 6. Mixed Your Choice: 0 Invalid Value: Please enter a value Enter the Type of Flower Order 1. Roses 2. Lilies 3. Daisies 4. Carnations 5. Live Plant 6. Mixed Your Choice: 4 Enter the Color 1. Red 2. White 3. Yellow 4. Pink 5. Orange 6. Blue 7. Lavender 8. Mixed Your Choice: 9 Invalid Value: Please enter a value Enter the Color 1. Red 2. White 3. Yellow 4. Pink 5. Orange 6. Blue 7. Lavender 8. Mixed Your Choice: 3 Enter the Type of Arrangement 1. Bouquet 2. Vase 3. Basket 4. Mixed Your Choice: 9 Invalid Value: Please enter a value Enter the Type of Arrangement

between 1 and 6

between 1 and 6

between 1 and 8

between 1 and 4 280

C# 3.0 Practical Learning

1. Bouquet 2. Vase 3. Basket 4. Mixed Your Choice: 5 Invalid Value: Please enter a value between 1 and 4 Enter the Type of Arrangement 1. Bouquet 2. Vase 3. Basket 4. Mixed Your Choice: 3 Enter the Unit Price: 54.95 Enter Quantity: 1 ======================= ==-=-=Flower Shop=-=-== ----------------------Flower Type: Carnations Flower Color: Yellow Arrangement: Basket Price: $54.95 Quantity: 1 Total Price: $54.95 ======================= Press any key to continue . . .

3. Close the DOS window

Breaking the Flow of a Conditional Statement
The break statement is used to stop a loop for any reason or condition when necessary. The formula of the break statement is:
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 break statement applies to the most previous conditional statement to it; provided that previous statement is applicable. The break statement can be used in a while condition, in a do…while or a for loops to stop an ongoing action. Here is an example that is used to count the levels of a house from 1 to 12 but it is asked to stop at 3:
using System; public class Exercise { public static int Main() { for (var Stories = 1; Stories <= 12; Stories++) { Console.WriteLine("Story {0}", Stories); if (Stories == 3) break;

C# 3.0 Practical Learning

281

} Console.WriteLine(); return 0;

} }

This would produce:
Story 1 Story 2 Story 3 Press any key to continue . . .

Continuing a Conditional 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, a 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. Here is an example when a program is supposed to count the levels of a house from 1 to 6:
using System; public class Exercise { public static int Main() { for (var Stories = 1; Stories <= 6; Stories++) { if (Stories == 3) continue; Console.WriteLine("Story {0}", Stories); } Console.WriteLine(); return 0; } }

This would produce:
Story Story Story Story Story 1 2 4 5 6

Press any key to continue . . .

Notice that, when the compiler gets to 3, it ignores it. C# 3.0 Practical Learning

282

Going to a Designated Label
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. Here is an example where the program is supposed to count the levels of a 14 story building:
using System; public class Exercise { public static int Main() { for (var Stories = 1; Stories <= 14; Stories++) { if (Stories == 4) goto CountUpTo3; Console.WriteLine("Story {0}", Stories); } CountUpTo3: Console.WriteLine("Our homes have only up to 3 levels\n"); return 0; } }

This would produce:
Story 1 Story 2 Story 3 Our homes have only up to 3 levels Press any key to continue . . .

Conditional Return
Some functions are meant to return a value that is conditional of their processing. The fact that a function indicates the type of value it would return may not be clear at the time the function is closed but a function defined other than void must always return a value. You can write a conditional statement, such as if, inside of a function and return a value from that condition. Here is an example:
using System; public class Program { enum HouseType { Unknown, SingleFamily, Townhouse, Condominium }; public static int Main() { var Type = GetHouseType();

C# 3.0 Practical Learning

283

switch (Type) { case HouseType.SingleFamily: Console.WriteLine("\nType break; case HouseType.Townhouse: Console.WriteLine("\nType break; case HouseType.Condominium: Console.WriteLine("\nType break; case HouseType.Unknown: Console.WriteLine("\nType break; } } return 0;

of Home: Single Family"); of Home: Townhouse"); of Home: Condominium"); of Home. Unknown");

private static HouseType GetHouseType() { var Type = 0; Console.WriteLine("What Type of House Would you Like to Purchase?"); Console.WriteLine("1 - Single Family"); Console.WriteLine("2 - Townhouse"); Console.WriteLine("3 - Condominium"); Console.Write("Your Choice? "); Type = int.Parse(Console.ReadLine()); if (Type == 1) return HouseType.SingleFamily; else if (Type == 2) return HouseType.Townhouse; else if (Type == 3) return HouseType.Condominium;

} }

This GetHouseType() method indicates when one of three values is returned. In reality, this method could get a value other than the three that are considered. If the user enters such a value, the current version of the method would not know what to do. For this reason, the program will not compile. In Microsoft Visual C#, you would receive the following error:
'Program.GetHouseType()': not all code paths return a value

To solve this problem, you must provide a statement that would include any value other than those considered. You can do this by writing a final return that has its own value. Here is an example:
using System; public class Program { enum HouseType { Unknown, SingleFamily, Townhouse, Condominium }; public static int Main()

C# 3.0 Practical Learning

284

{ var Type = GetHouseType(); switch (Type) { case HouseType.SingleFamily: Console.WriteLine("\nType break; case HouseType.Townhouse: Console.WriteLine("\nType break; case HouseType.Condominium: Console.WriteLine("\nType break; case HouseType.Unknown: Console.WriteLine("\nType break; } } return 0;

of Home: Single Family"); of Home: Townhouse"); of Home: Condominium"); of Home. Unknown");

private static HouseType GetHouseType() { var Type = 0; Console.WriteLine("What Type of House Would you Like to Purchase?"); Console.WriteLine("1 - Single Family"); Console.WriteLine("2 - Townhouse"); Console.WriteLine("3 - Condominium"); Console.Write("Your Choice? "); Type = int.Parse(Console.ReadLine()); if (Type == 1) return HouseType.SingleFamily; else if (Type == 2) return HouseType.Townhouse; else if (Type == 3) return HouseType.Condominium; else return HouseType.Unknown;

} }

Recursion
Introduction
Imagine that you want to count the positive odd numbers from a certain maximum to a certain minimum. For example, to count the odd numbers from 1 to 9, you would use: 9, 7, 5, 3, and 1 Notice that, to perform this operation, you consider the highest. Then you subtract 2 to get the previous. Again, you subtract 2 from the number to get 285 C# 3.0 Practical Learning

the previous. What you are simply doing is to subtract a constant to what you already have and you invent very little. In computer programming, you can solve this type of problem by first writing a function, and then have the function call itself. This is the basis for recursion.

Creating a Recursive Methods
A type of formula to create a recursive method is:
ReturnValue Function(Arguments, if any) { Optional Action . . . Function(); Optionan Action . . . }

A recursive method starts with a return value. If it would not return a value, you can define it with void. After its name, the method can take one or more arguments. Most of the time, a recursive method takes at least one argument that it would then modify. In the body of the method, you can take the necessary actions. There are no particular steps to follow when implementing a recursive method but there are two main rules to observe:
• •

In its body, the method must call itself Before or after calling itself, the method must check a condition that would allow it to stop, otherwise, it might run continuously

For our example of counting decrementing odd numbers, you could start by creating a method that takes an integer as argument. To exercise some control on the lowest possible values, we will consider only positive numbers. In the body of the method, we will display the current value of the argument, subtract 2, and recall the method itself. Here is our function:
using System; public class Exercise { static void OddNumbers(int a) { if (a >= 1) { Console.Write("{0}, ", a); a -= 2; OddNumbers(a); } } public static int Main() { const int Number = 9; Console.WriteLine("Odd Numbers"); OddNumbers(Number); Console.WriteLine(); return 0;

}

C# 3.0 Practical Learning

286

}

Notice that the method calls itself in its body. This would produce:
Odd Numbers 9, 7, 5, 3, 1, Press any key to continue . . .

Using Recursive Methods
Recursive methods provide a valuable mechanism for building lists or series, which are value that are either increment or decrement but follow a pattern. Imagine that, instead of simply displaying odd numbers as we did above, you want to add them incrementally. If you have 1, it would also produce 1. If you have 5, you would like to add 1 to 3, then the result to 5, and so on. This can be illustrated as follows:
= 1 = 4 = 9 1 1 + 3 1 + 3 + 5

1 + 3 + 5 + 7 = 16 1 + 3 + 5 + 7 + 9 = 25

To perform this operation, you would consider 1. If the number is less than or equal to 1, the method should return 1. Otherwise, add 2 to 1, then add 2 to the new result. Continue this until you get to the value of the argument. The method can be implemented as follows:
using System; public class Exercise { static int AdditionalOdd(int a) { if (a <= 1) return 1; return a + AdditionalOdd(a - 2); } static void OddNumbers(int a) { if (a >= 1) { Console.Write("{0}, ", a); a -= 2; OddNumbers(a); } } public static int Main() { const int Number = 9;

C# 3.0 Practical Learning

287

Console.WriteLine("Odd Numbers"); OddNumbers(Number); Console.WriteLine(); Console.WriteLine("Sum of Odds: {0}\n", AdditionalOdd(Number)); return 0; } }

This would produce:
Odd Numbers 9, 7, 5, 3, 1, Sum of Odds: 25 Press any key to continue . . .

C# 3.0 Practical Learning

288

THE PROPERTIES OF A CLASS
Overview of Properties
Introduction
In C++ and Java, when creating the 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 accessible outside of 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 to access or get the value of such a field, you must then create one or two "accessories", like a door in which the external classes must pass through to access the field.

Accessories for Properties
A property is a member of a class that plays an intermediary role to a field of the class. For example, if you have a field of class and that member represents the salary of an employee, a property can be the "door" that other classes that need the salary must present their requests to. As such, these external classes 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. A property is used to "filter" access to a field of a class. Therefore, you start by declaring a (private (if you don't make it private, you may be deceiving the purpose of creating a property)) field. Here is an example:
using System; public class Square { private double _side; } public class Exercise { public static int Main() { return 0;

C# 3.0 Practical Learning

289

} }

Obviously this private field cannot be accessed by an outside class. To let the outside classes access this variable, you would/can create a property. To indicate that you are creating a property, there is a syntax you must follow. To start, you must create a member whose formula resembles a method without the parentheses. Since or if the property will be accessed by only by objects of the same program, you can mark it with the internal keyword. If the property will be accessed by objects of this and other programs, you should mark it as public. Therefore, you would start a property as follows:
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 Microsoft Visual C# and create a Console Application named
DepartmentStore2

2. To create a new class, on the main menu, click Project -> Add Class... 3. Set the Name to ShoppingItem and press Enter 4. Change the content of the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore2 { class DepartmentStore { private long itemNo; private string nm; private string sz; private decimal price; } }

5. To create a property for each member variable, change the ShoppingItem class as follows:
using System; using System.Collections.Generic;

C# 3.0 Practical Learning

290

using System.Linq; using System.Text; namespace DepartmentStore2 { class ShoppingItem { private string itemNo; private string nm; private string sze; private decimal price; // A property for the stock number of an item public string ItemNumber { } // A property for the name of an item public string Name { } // A property for size of a merchandise public string Size { } // A property for the marked price of an item public decimal UnitPrice { } } }

6. 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 keyword, using the traditional curly brackets that delimit a section of code. Here is an example:
public class Square { private double _side; // This is a new property public double Side { get {

C# 3.0 Practical Learning

291

} } }

In the body of the get clause, you can implement the behavior that would be used to make the field's value available outside. The simplest way consists of just returning the corresponding field. Here is an example:
public class Square { private double _side; // This is a new property public double Side { get { return _side; } }

}

A read property is also referred to as 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:
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 can access it, for example they can read its value as follows:
using System; public class Square { private double _side; // This is a new property

C# 3.0 Practical Learning

292

public double Side { get { return _side; } } public Square(double s) { _side = s; }

}

public class Exercise { public static int Main() { var sq = new Square(-25.55); Console.WriteLine("Square Side: {0}", sq.Side); return 0;

} }

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 field, preventing those outside classes to mess with 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 field as private, you can use the read property to reset the value of the field 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; public class Square { private double _side; // This is a new property public double Side { get { // If the value given to the side is negative, // then set it to 0 if (_side < 0) return 0; else return _side; } }

C# 3.0 Practical Learning

293

public Square(double s) { _side = s; } } public class Exercise { public static int Main() { var sq1 = new Square(-12.48); var 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); return 0;

} }

This would produce:
First Square Characteristics Side: 0 Second Square Characteristics Side: 25.55

Practical Learning: Creating Property Readers
1. To create read properties, change the contents of the ShoppingStore.cs file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore2 { class ShoppingItem { private long itemNo; private string nm; private string sz; private decimal price; // A property for the stock number of an item public long ItemNumber { get { return itemNo; } }

C# 3.0 Practical Learning

294

// A property for the name of an item public string Name { get { return nm; } } // A property for size of a merchandise public string Size { get { if( sz == "0" ) return "Unknown Size or Fits All"; else return sz; } } // A property for the marked price of an item public decimal UnitPrice { get { return price; } } // A constructor used to initialize an item public ShoppingItem(long nbr, string nme, string siz, decimal prc) { itemNo = nbr; nm = nme; sz = siz; price = prc; }

} }

2. Access the Program.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore2 { class Program { static void Main() { long number;

C# 3.0 Practical Learning

295

string name; string size; decimal price; Console.WriteLine("/-/Arrington Department Store/-/"); Console.Write("Enter the Item #: "); number = long.Parse(Console.ReadLine()); Console.Write("Enter the Item Name: "); name = Console.ReadLine(); Console.Write("Enter the Item Size: "); size = Console.ReadLine(); Console.Write("Enter the Unit Price: "); price = decimal.Parse(Console.ReadLine()); ShoppingItem store = new ShoppingItem(number, name, size, price); Console.WriteLine("\n================================"); Console.WriteLine("/-/Arrington Department Store/-/"); Console.WriteLine("--------------------------------"); Console.WriteLine("Customer Invoice"); Console.WriteLine("Item #: {0}", store.ItemNumber); Console.WriteLine("Description: {0}", store.Name); Console.WriteLine("Item Size: {0}", store.Size); Console.WriteLine("Unit Price: {0:C}", store.UnitPrice); Console.WriteLine("================================\n");

} } }

3. Execute the program:

/-/Arrington Department Store/-/ Enter the Item #: 622805 Enter the Item Name: Black Leather Hand Bag Enter the Item Size: Medium Enter the Unit Price: 85.95 ================================ /-/Arrington Department Store/-/ --------------------------------

C# 3.0 Practical Learning

296

Customer Invoice Item #: 622805 Description: Black Leather Hand Bag Item Size: Medium Unit Price: $85.95 ================================ Press any key to continue . . .

4. Close the DOS window

Property Writers
In our Square class so far, we were using a constructor to create a value for each of the necessary member variables. This meant that we had to always make sure that we knew the value of the field when we declared an instance of the class. Sometimes, this is not effective. For example, you cannot just call a constructor in the middle of the program, that is after the object has been declared, to assign a new value to the field. To solve this kind of problem, you can provide another means of accessing the field any time to change its value. Besides, or instead of, retrieving the value of a field of a class, you may want external classes to be able to change the value of that member. Continuing with our concern to hide a field as private, you can create another type of property. A property is referred to as write if it can change (or write) the value of its corresponding field.

To create a write property, type the set keyword followed by the curly bracket delimiters. Here is an example:
public class Square { private double _side; // This is a new property public double Side { set { } }

}

The minimum assignment you can perform with a write property is to assign it a value that would be provided by the outside world. To support this, C# provides the value contextual keyword (contextual means the word is a keyword only in some cases, depending on how it is being used). Here is an example:
public class Square { private double _side;

C# 3.0 Practical Learning

297

// This is a new property public double Side { set { _side = value; } } }

As you see, clients of a class can change the corresponding field of a member variable through the property writer. Based on this relationship, it is not unusual for a client of a class to make an attempt to "mess" with a field. For example, an external object can assign an invalid value to a member variable. Consider the following program:
using System; public class Square { public double _side; // This is a new property public double Side { set { _side = value; } } public Square() { _side = 0; } public Square(double s) { _side = s; } public double Perimeter() { return _side * 4; } public double Area() { return _side * _side; }

}

public class Exercise { public static int Main() { var sq1 = new Square(); var sq2 = new Square();

C# 3.0 Practical Learning

298

sq1._side = -12.48; sq2._side = 25.55; Console.WriteLine("First Square Characteristics"); Console.WriteLine("Side: {0}", sq1._side); Console.WriteLine("Perimeter: {0}", sq1.Perimeter()); Console.WriteLine("Area: {0}\n", sq1.Area()); Console.WriteLine("Second Square Characteristics"); Console.WriteLine("Side: {0}", sq2._side); Console.WriteLine("Perimeter: {0}", sq2.Perimeter()); Console.WriteLine("Area: {0}", sq2.Area()); } } return 0;

This would produce:
First Square Characteristics Side: -12.48 Perimeter: -49.92 Area: 155.7504 Second Square Characteristics Side: 25.55 Perimeter: 102.2 Area: 652.8025 Press any key to continue...

Because of this, and since it is through the writer that the external objects would change the value of the member variable, you can use the write property, rather than the reader, to validate or reject a new value assigned to the field. Remember that the client objects of the class can only read the value of the field through the read property. Therefore, there may be only little concern on that side.

Read/Write Properties
If you create a property that has only a set section, the property is referred to as write-only because the other classes can only assign it a value (or write a value to it). If you create a property that has both a get and a set sections, its corresponding member variable can receive new values from outside the class and the member variable can provide its values to clients of the class. Such a property is referred to as read/write.

Practical Learning: Creating Property Writers
1. To create property writers and complete the program, change the content of the ShoppingItem.cs file as follows:
using System; using System.Collections.Generic;

C# 3.0 Practical Learning

299

using System.Linq; using System.Text; namespace DepartmentStore2 { class ShoppingItem { private long itemNo; private string nm; private string sz; private decimal price; // A property for the stock number of an item public long ItemNumber { get { return itemNo; } set {

} }

if (itemNo <= 0) itemNo = 0; else itemNo = value;

// A property for the name of an item public string Name { get { return nm; } set { if (nm == "") nm = "Item no Description"; else nm = value; } }

// A property for size of a merchandise public string Size { get { if( sz == "0" ) return "Unknown Size or Fits All"; else return sz; } set { sz = value;

C# 3.0 Practical Learning

300

} } // A property for the marked price of an item public decimal UnitPrice { get { return price; } set { if (price < 0) price = 0.00M; else price = value; } }

public static ShoppingItem Read() { ShoppingItem shop = new ShoppingItem(); Console.Write("Item #: "); shop.itemNo = long.Parse(Console.ReadLine()); Console.Write("Item Name: "); shop.Name = Console.ReadLine(); Console.Write("Item Size (Enter 0 if unknown): "); shop.Size = Console.ReadLine(); Console.Write("Unit Price: "); shop.UnitPrice = decimal.Parse(Console.ReadLine()); } return shop;

public static void Write(ShoppingItem item) { Console.WriteLine("Item #: {0}", item.ItemNumber); Console.WriteLine("Description: {0}", item.Name); Console.WriteLine("Item Size: {0}", item.Size); Console.WriteLine("Unit Price: {0:C}", item.UnitPrice); } } }

2. Access the Program.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore2 { class Program { static void Main() {

C# 3.0 Practical Learning

301

Console.WriteLine("/-/Arrington Department Store/-/"); Console.Write("Enter the following pieces of "); Console.WriteLine("information about the sale item"); ShoppingItem saleItem = ShoppingItem.Read(); Console.WriteLine("\n================================"); Console.WriteLine("/-/Arrington Department Store/-/"); Console.WriteLine("--------------------------------"); ShoppingItem.Write(saleItem); } } }

3. Execute the program. Here is an example:

/-/Arrington Department Store/-/ Enter the following pieces of information about the sale item Item #: 114888 Item Name: North Hook Alpine Jacket Item Size (Enter 0 if unknown): Large Unit Price: 275.95 ================================ /-/Arrington Department Store/-/ -------------------------------Item #: 114888 Description: North Hook Alpine Jacket Item Size: Large Unit Price: $275.95 Press any key to continue . . .

4. Close the DOS window

A Boolean Property

C# 3.0 Practical Learning

302

You can create a property as a Boolean type. To do this, first specify its data type as bool. When treating the property, make sure its get accessory returns a Boolean type. A Boolean property is not like the other regular properties. It must specify its value as true or false. As done for Boolean methods, a Boolean property must produce only a true or false value.

Properties of External Classes
Properties and Enumerations
An enumeration is a technique of creating data type that mimics an integer. After creating it, you can treat it as a pseudo data type. You can declare a variable from it, you can pass it as an argument, and you can return it from a method. Based on these characteristics, you can create a property that is based on an enumeration. To create an enumeration property, you use the same formula as one of the primitive data types we have used previously. Keep it mind that the property is of the type of an enumeration. This means that you cannot request its value like that of a primitive type and, when manipulating it, you must process it appropriately.

Practical Learning: Creating an Enumeration Property
1. Access the ShoppingStore.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore2 { public enum ItemCategory { Unspecified, Women, Men, Girls, Boys, Babies } class ShoppingItem { private long itemNo; private ItemCategory cat; private string nm; private string sz; private decimal price; // A property for the stock number of an item

C# 3.0 Practical Learning

303

public long ItemNumber { get { return itemNo; } set { if (itemNo <= 0) itemNo = 0; else itemNo = value; } }

// A property for the category of item public ItemCategory Category { get { return cat; } set { } }

cat = value;

// A property for the name of an item public string Name { get { return nm; } set {

} }

if (nm == "") nm = "Item no Description"; else nm = value;

// A property for size of a merchandise public string Size { get { if( sz == "0" ) return "Unknown Size or Fits All"; else return sz; } set {

C# 3.0 Practical Learning

304

sz = value; } }

// A property for the marked price of an item public decimal UnitPrice { get { return price; } set {

} }

if (price < 0) price = 0.00M; else price = value;

public static ShoppingItem Read() { int category = 0; ShoppingItem shop = new ShoppingItem(); Console.Write("Item #: "); shop.itemNo = long.Parse(Console.ReadLine()); Console.WriteLine("Store Items Categories"); Console.WriteLine("\t1. Women"); Console.WriteLine("\t2. Men"); Console.WriteLine("\t3. Girls"); Console.WriteLine("\t4. Boys"); Console.WriteLine("\t5. Babies"); Console.Write("Enter the Category: "); category = int.Parse(Console.ReadLine()); if (category == 1) shop.Category = ItemCategory.Women; else if (category == 2) shop.Category = ItemCategory.Men; else if (category == 3) shop.Category = ItemCategory.Girls; else if (category == 4) shop.Category = ItemCategory.Boys; else if (category == 5) shop.Category = ItemCategory.Babies; else shop.Category = ItemCategory.Unspecified; Console.Write("Item Name: "); shop.Name = Console.ReadLine(); Console.Write("Item Size (Enter 0 if unknown): "); shop.Size = Console.ReadLine(); Console.Write("Unit Price: "); shop.UnitPrice = decimal.Parse(Console.ReadLine()); } return shop;

public static void Write(ShoppingItem item) {

C# 3.0 Practical Learning

305

Console.WriteLine("Item #: Console.WriteLine("Category: Console.WriteLine("Description: Console.WriteLine("Item Size: Console.WriteLine("Unit Price: } } }

{0}", item.ItemNumber); {0}", item.Category); {0}", item.Name); {0}", item.Size); {0:C}", item.UnitPrice);

2. Execute the application and test it. Here is an example:

/-/Arrington Department Store/-/ Enter the following pieces of information about the sale item Item #: 624008 Store Items Categories 1. Women 2. Men 3. Girls 4. Boys 5. Babies Enter the Category: 3 Item Name: Scotta Miniskirt Item Size (Enter 0 if unknown): 11 Unit Price: 35.95 ================================ /-/Arrington Department Store/-/ -------------------------------Item #: 624008 Category: Girls Description: Scotta Miniskirt Item Size: 11 Unit Price: $35.95 Press any key to continue . . .

3. Close the DOS window

A Class as a Property
Remember that, after creating a class, it becomes a data type in its own right. We have seen that you could declare a variable from it, you could pass it as argument, and you could return it from a method. As a normal data type, C# 3.0 Practical Learning
306

a class can be validated. This means that its value can be evaluated, rejected, or retrieved. Based on these characteristics of a class, you can create a property from it. To create a property that is based on a class, primarily follow the same formulas we have applied to the other properties. The most important aspect to remember is that the class is composite. That is, it is (likely) made of fields of various types.

Practical Learning: Creating a Property of a Class Type
1. Access the ShoppingItem.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore2 { public enum ItemCategory { Unspecified, Women, Men, Girls, Boys, Babies } class ShoppingItem { private long itemNo; private ItemCategory cat; private string nm; private string sz; private decimal price; // A property for the stock number of an item public long ItemNumber { get { return itemNo; } set { } } // A property for the category of item public ItemCategory Category { get { itemNo = value;

C# 3.0 Practical Learning

307

return cat; } set { } } // A property for the name of an item public string Name { get { return nm; } set { if (nm == "") nm = "Item no Description"; else nm = value; } } cat = value;

// A property for size of a merchandise public string Size { get { if (sz == "0") return "Unknown Size or Fits All"; else return sz; } set { } } // A property for the marked price of an item public decimal UnitPrice { get { return price; } set { if (price < 0) price = 0.00M; else price = value; } } } sz = value;

C# 3.0 Practical Learning

308

}

2. To create a new class, in the Solution Explorer, right-click the name of the project, position the mouse on Add and click Class... 3. Set the Name to DepartmentStore and click Add 4. Change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore2 { class DepartmentStore { private int qty; private ShoppingItem itm; public int Quantity { get { return qty; } set { if (qty <= 0) qty = 0; else qty = value; } } public ShoppingItem SaleItem { get { return itm; } set { if (itm == null) { itm.ItemNumber = 0; itm.Category = ItemCategory.Unspecified; itm.Name = "Unknown"; itm.Size = "0"; itm.UnitPrice = 0.00M; } else itm = value; } } public DepartmentStore() { itm = new ShoppingItem(); } public void ProcessOrder() { int category;

C# 3.0 Practical Learning

309

Console.WriteLine("/-/Arrington Department Store/-/"); Console.WriteLine("Enter the following pieces of"); Console.WriteLine("information about the sale item"); Console.Write("Item #: "); itm.ItemNumber = long.Parse(Console.ReadLine()); Console.WriteLine("Store Items Categories"); Console.WriteLine("\t1. Women"); Console.WriteLine("\t2. Men"); Console.WriteLine("\t3. Girls"); Console.WriteLine("\t4. Boys"); Console.WriteLine("\t5. Babies"); Console.Write("Enter the Category: "); category = int.Parse(Console.ReadLine()); if (category == 1) itm.Category = ItemCategory.Women; else if (category == 2) itm.Category = ItemCategory.Men; else if (category == 3) itm.Category = ItemCategory.Girls; else if (category == 4) itm.Category = ItemCategory.Boys; else if (category == 5) itm.Category = ItemCategory.Babies; else itm.Category = ItemCategory.Unspecified; Console.Write("Item Name: "); itm.Name = Console.ReadLine(); Console.Write("Item Size (Enter 0 if unknown): "); itm.Size = Console.ReadLine(); Console.Write("Unit Price: "); itm.UnitPrice = decimal.Parse(Console.ReadLine()); Console.Write("How many samples of "); Console.Write(itm.Name); Console.Write(": "); qty = int.Parse(Console.ReadLine()); } public void DisplayReceipt() { decimal totalPrice = itm.UnitPrice * Quantity; Console.WriteLine("\n================================"); Console.WriteLine("/-/Arrington Department Store/-/"); Console.WriteLine("--------------------------------"); Console.WriteLine("Item #: {0}", itm.ItemNumber); Console.WriteLine("Category: {0}", itm.Category); Console.WriteLine("Description: {0}", itm.Name); Console.WriteLine("Item Size: {0}", itm.Size); Console.WriteLine("Unit Price: {0:C}", itm.UnitPrice); Console.WriteLine("Quantity: {0}", Quantity); Console.WriteLine("Total Price: {0:C}\n", totalPrice); Console.WriteLine("\n================================");

} } }

5. Access the Program.cs file and change it as follows: C# 3.0 Practical Learning
310

using using using using

System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore2 { class Program { static void Main() { DepartmentStore store = new DepartmentStore(); store.ProcessOrder(); store.DisplayReceipt(); } } }

6. Execute the application and test it. Here is an example:

/-/Arrington Department Store/-/ Enter the following pieces of information about the sale item Item #: 444412 Store Items Categories 1. Women 2. Men 3. Girls 4. Boys 5. Babies Enter the Category: 1 Item Name: Stretch Cotton Shirt Item Size (Enter 0 if unknown): 14 Unit Price: 55.95 How many samples of Stretch Cotton Shirt: 2 ================================ /-/Arrington Department Store/-/ -------------------------------Item #: 444412 Category: Women Description: Stretch Cotton Shirt Item Size: 14

C# 3.0 Practical Learning

311

Unit Price: $55.95 Quantity: 2 Total Price: $111.90 ================================ Press any key to continue . . .

7. Close the DOS window

C# 3.0 Practical Learning

312

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. On the other hand, 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 basketball 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.

Practical Learning: Introducing Inheritance
C# 3.0 Practical Learning
313

1. Start Microsoft Visual C# 2005 Express Edition and create a new Console Application named RealEstate2 2. To create a new class, in the Class View, right-click the name of the project, position the mouse on Add and click Class... 3. Set the Name to Property and press Enter 4. Change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace RealEstate2 { public enum PropertyCondition { Unknown, Excellent, Good, NeedsRepair, BadShape } public class Property { private private private private private private string propNbr; PropertyCondition cond; int beds; float baths; int yr; decimal val;

public Property() { } public string PropertyNumber { get { return propNbr; } set

C# 3.0 Practical Learning

314

{ if (propNbr == "") propNbr = "N/A"; else propNbr = value; } }

public PropertyCondition Condition { get { return cond; } set { cond = value; } } public int Bedrooms { get { if (beds <= 1) return 1; else return beds; } set { beds = value; } } public float Bathrooms { get { return baths; } set { baths = value; } } public int YearBuilt { get { return yr; } set { yr = value; } } public decimal Value { get { return val; } set { val = value; } } } }

5. To create a new class, in the Solution Explorer, right-click the name of the project, position the mouse on Add and click Class... 6. Set the Name to PropertyListing and press Enter 7. Change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace RealEstate2

C# 3.0 Practical Learning

315

{ public enum PropertyType { Unknown, SingleFamily, Townhouse,

Condominium
} public class PropertyListing { private Property prop; private PropertyType tp; public Property ListProperty { get { return prop; } set { prop = value; } } public PropertyType Type { get { return tp; } set { tp = value; } } public PropertyListing() { prop = new Property(); } public void CreateListing() { Console.WriteLine(" =//= Altair Realty =//="); Console.WriteLine("-=- Property Creation -=-"); Console.WriteLine("\nTypes of Properties"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condonium"); Console.WriteLine("4. Don't Know"); Console.Write("Enter Type of Property: "); int propType = int.Parse(Console.ReadLine()); Console.Write("\nEnter Property #: "); ListProperty.PropertyNumber = Console.ReadLine(); Console.WriteLine("\nProperties Conditions"); Console.WriteLine("1. Excellent"); Console.WriteLine("2. Good (may need minor repair)"); Console.WriteLine("3. Needs Repair"); Console.Write("4. In Bad Shape (property needs "); Console.WriteLine("major repair or rebuild)"); Console.Write("Enter Property Condition: "); int condition = int.Parse(Console.ReadLine()); if (condition == 1) ListProperty.Condition = PropertyCondition.Excellent; else if (condition == 2) ListProperty.Condition = PropertyCondition.Good;

C# 3.0 Practical Learning

316

else if (condition == 3) ListProperty.Condition = PropertyCondition.NeedsRepair; else if (condition == 4) ListProperty.Condition = PropertyCondition.BadShape; else ListProperty.Condition = PropertyCondition.Unknown; switch ((PropertyType)propType) { case PropertyType.SingleFamily: Type = PropertyType.SingleFamily; break; case PropertyType.Townhouse: Type = PropertyType.Townhouse; break; case PropertyType.Condominium: Type = PropertyType.Condominium; break; default: Type = PropertyType.Unknown; break;

}

Console.Write("\nHow many bedrooms? "); ListProperty.Bedrooms = int.Parse(Console.ReadLine()); Console.Write("How many bathrooms? "); ListProperty.Bathrooms = float.Parse(Console.ReadLine()); Console.Write("Year built: "); ListProperty.YearBuilt = int.Parse(Console.ReadLine()); Console.Write("Property Value: } ");

ListProperty.Value = decimal.Parse(Console.ReadLine());

public void ShowProperty() { Console.WriteLine("=================================="); Console.WriteLine(" =//=//= Altair Realty =//=//="); Console.WriteLine("-=-=-=- Properties Listing -=-=-=-"); Console.WriteLine("----------------------------------"); Console.WriteLine("Property #: {0}", ListProperty.PropertyNumber); Console.WriteLine("Property Type: {0}", Type); switch (Type) { case PropertyType.SingleFamily: case PropertyType.Townhouse: Type = PropertyType.SingleFamily; break; case PropertyType.Condominium: break; } Console.WriteLine("Condition: {0}", 317

C# 3.0 Practical Learning

} } }

ListProperty.Condition); Console.WriteLine("Bedrooms: {0}", ListProperty.Bedrooms); Console.WriteLine("Bathrooms: {0}", ListProperty.Bathrooms); Console.WriteLine("Year Built: {0}", ListProperty.YearBuilt); Console.WriteLine("Market Value: {0:C}", ListProperty.Value); Console.WriteLine("==================================");

8. Access the Program.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace RealEstate2 { class Program { static void Main() { PropertyListing listing = new PropertyListing(); listing.CreateListing(); Console.WriteLine("\n"); listing.ShowProperty(); Console.WriteLine();

} } }

9. Execute the application and test it. Here is an example:
=//= Altair Realty =//= -=- Property Creation -=Types of Properties 1. Single Family 2. Townhouse 3. Condominium 4. Don't Know Enter Type of Property: 2 Enter Property #: 66DG8P Properties Conditions 1. Excellent 2. Good (may need minor repair) 3. Needs Repair 4. In Bad Shape (property needs major repair or rebuild) Enter Property Condition: 2

C# 3.0 Practical Learning

318

How many bedrooms? How many bathrooms? Year built: Property Value:

2 1.0 1994 325880.75

================================== =//=//= Altair Realty =//=//= -=-=-=- Properties Listing -=-=-=---------------------------------Property #: 66DG8P Property Type: Townhouse Condition: Good Bedrooms: 2 Bathrooms: 1 Year Built: 1994 Market Value: $325,880.75 ================================== Press any key to continue . . .

10.

Close the DOS window

Class Derivation
As you may have guessed, 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; public class Circle { private double _radius; public double Radius { get { return _radius; } set { if( _radius < 0 ) _radius = 0.00; else _radius = value; } } public double Diameter { get { return Radius * 2; } } public double Circumference

C# 3.0 Practical Learning

319

{ get { } } public double Area { get { return Radius * Radius * 3.14159; } } return Diameter * 3.14159;

}

class Exercise { public static int Main() { var Round = new Circle(); Round.Radius = 25.55; Console.WriteLine("Circle Characteristics"); Console.WriteLine("Side: {0}", Round.Radius); Console.WriteLine("Diameter: {0}", Round.Diameter); Console.WriteLine("Circumference: {0}", Round.Circumference); Console.WriteLine("Area: {0}", Round.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 3dimensional 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: 320 C# 3.0 Practical Learning

class NewChild : BaseClass { // 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 BaseClass 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; 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

C# 3.0 Practical Learning

321

{ } } } return Radius * Radius * 3.14159;

class Sphere : Circle { } class Exercise { public static int Main() { var Round = new Circle(); Round.Radius = 25.55; Console.WriteLine("Circle Characteristics"); Console.WriteLine("Side: {0}", Round.Radius); Console.WriteLine("Diameter: {0}", Round.Diameter); Console.WriteLine("Circumference: {0}", Round.Circumference); Console.WriteLine("Area: {0}", Round.Area); var Ball = new Sphere(); Ball.Radius = 25.55; Console.WriteLine("\nSphere Characteristics"); Console.WriteLine("Side: {0}", Ball.Radius); Console.WriteLine("Diameter: {0}", Ball.Diameter); Console.WriteLine("Circumference: {0}", Ball.Circumference); Console.WriteLine("Area: {0}", Ball.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 inheritance-oriented 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 C# 3.0 Practical Learning
322

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; } } 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 {

C# 3.0 Practical Learning

323

}

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() { var Round = new Circle(); Round.Radius = 25.55; Round.ShowCharacteristics(); var Ball = new Sphere(); Ball.Radius = 25.55; Ball.ShowCharacteristics(); return 0; } }

This would produce the same result.

Practical Learning: Inheriting
1. On the main menu, click Project -> Add -> Class... 2. Set the Name to HouseType and press Enter 3. To derive a class, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace RealEstate2 { public class HouseType : Property { private int nbrOfStories; private bool basement; private bool garage; public int Stories { get { return nbrOfStories; } set { nbrOfStories = value; } }

C# 3.0 Practical Learning

324

public bool FinishedBasement { get { return basement; } set { basement = value; } } public bool IndoorGarage { get { return garage; } set { garage = value; } }

} }

4. On the main menu, click Project -> Add -> Class... 5. Set the Name to Condominium and press Enter 6. To create another class based on the Property class, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace RealEstate2 { public class Condominium : Property { private bool handicap; public bool HandicapAccessible { get { return handicap; } set { handicap = value; } }

} }

7. Access the PropertyListing.cs file file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace RealEstate2 { public enum PropertyType { Unknown, SingleFamily, Townhouse, Condominium }

C# 3.0 Practical Learning

325

class PropertyListing { private Property prop; private HouseType hse; private Condominium cond; private PropertyType tp; public Property ListProperty { get { return prop; } set { prop = value; } } public HouseType House { get { return hse; } set { hse = value; } } public Condominium Condo { get { return cond; } set { cond = value; } } public PropertyType Type { get { return tp; } set { tp = value; } } public PropertyListing() { prop = new Property(); hse = new HouseType(); cond = new Condominium(); } public void CreateListing() { char answer; Console.WriteLine(" =//= Altair Realty =//="); Console.WriteLine("-=- Property Creation -=-"); Console.WriteLine("\nTypes of Properties"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condonium"); Console.WriteLine("4. Don't Know"); Console.Write("Enter Type of Property: "); int propType = int.Parse(Console.ReadLine()); Console.Write("\nEnter Property #: "); ListProperty.PropertyNumber = Console.ReadLine(); Console.WriteLine("\nProperties Conditions"); Console.WriteLine("1. Excellent");

C# 3.0 Practical Learning

326

Console.WriteLine("2. Good (may need minor repair)"); Console.WriteLine("3. Needs Repair"); Console.Write("4. In Bad Shape (property needs "); Console.WriteLine("major repair or rebuild)"); Console.Write("Enter Property Condition: "); int condition = int.Parse(Console.ReadLine()); if (condition == 1) ListProperty.Condition = PropertyCondition.Excellent; else if (condition == 2) ListProperty.Condition = PropertyCondition.Good; else if (condition == 3) ListProperty.Condition = PropertyCondition.NeedsRepair; else if (condition == 4) ListProperty.Condition = PropertyCondition.BadShape; else ListProperty.Condition = PropertyCondition.Unknown; switch ((PropertyType)propType) { case PropertyType.SingleFamily: Type = PropertyType.SingleFamily; Console.Write("\nHow many stories (levels)? "); House.Stories = int.Parse(Console.ReadLine()); Console.Write("Does it have an indoor car garage (y/n): answer = char.Parse(Console.ReadLine()); if ((answer == 'y') || (answer == 'Y')) House.IndoorGarage = true; else House.IndoorGarage = false; Console.Write("Is the basement finished(y/n): "); answer = char.Parse(Console.ReadLine()); if ((answer == 'y') || (answer == 'Y')) House.FinishedBasement = true; else House.FinishedBasement = false; break; case PropertyType.Townhouse: Type = PropertyType.Townhouse; Console.Write("\nHow many stories (levels)? "); House.Stories = int.Parse(Console.ReadLine()); Console.Write("Does it have an indoor car garage (y/n): "); answer = char.Parse(Console.ReadLine()); if ((answer == 'y') || (answer == 'Y')) House.IndoorGarage = true; else House.IndoorGarage = false; Console.Write("Is the basement finished(y/n): "); answer = char.Parse(Console.ReadLine()); if ((answer == 'y') || (answer == 'Y')) House.FinishedBasement = true; else House.FinishedBasement = false; break; case PropertyType.Condominium: Type = PropertyType.Condominium;

");

C# 3.0 Practical Learning

327

Console.Write("\nIs the building accessible to handicapped (y/n): "); answer = char.Parse(Console.ReadLine()); if ((answer == 'y') || (answer == 'Y')) Condo.HandicapAccessible = true; else Condo.HandicapAccessible = false; break; default: Type = PropertyType.Unknown; break;

}

}

Console.Write("\nHow many bedrooms? "); ListProperty.Bedrooms = int.Parse(Console.ReadLine()); Console.Write("How many bathrooms? "); ListProperty.Bathrooms = float.Parse(Console.ReadLine()); Console.Write("Year built: "); ListProperty.YearBuilt = int.Parse(Console.ReadLine()); Console.Write("Property Value: "); ListProperty.Value = decimal.Parse(Console.ReadLine());

public void ShowProperty() { Console.WriteLine("=================================="); Console.WriteLine(" =//=//= Altair Realty =//=//="); Console.WriteLine("-=-=-=- Properties Listing -=-=-=-"); Console.WriteLine("----------------------------------"); Console.WriteLine("Property #: {0}", ListProperty.PropertyNumber); Console.WriteLine("Property Type: {0}", Type); switch(Type) { case PropertyType.SingleFamily: case PropertyType.Townhouse: Type = PropertyType.SingleFamily; Console.WriteLine("Stories: {0}", House.Stories); Console.WriteLine("Has Indoor Car Garage: {0}", House.IndoorGarage); Console.WriteLine("Finished Basement: {0}", House.FinishedBasement); break; case PropertyType.Condominium: Console.WriteLine("Handicapped Accessible Building: {0}", } Condo.HandicapAccessible); break; {0}", {0}", {0}", 328

Console.WriteLine("Condition: ListProperty.Condition); Console.WriteLine("Bedrooms: ListProperty.Bedrooms); Console.WriteLine("Bathrooms: ListProperty.Bathrooms);

C# 3.0 Practical Learning

Console.WriteLine("Year Built: ListProperty.YearBuilt); Console.WriteLine("Market Value: ListProperty.Value); } } }

{0}", {0:C}",

8. Execute the application and test it. Here is an example:
=//= Altair Realty =//= -=- Property Creation -=Types of Properties 1. Single Family 2. Townhouse 3. Condonium 4. Don't Know Enter Type of Property: 1 Enter Property #: 4LP804 Properties Conditions 1. Excellent 2. Good (may need minor repair) 3. Needs Repair 4. In Bad Shape (property needs major repair or rebuild) Enter Property Condition: 3 How many stories (levels)? 3 Does it have an indoor car garage (y/n): y Is the basement finished(y/n): n How many bedrooms? How many bathrooms? Year built: Property Value: 4 2.5 1996 640885.80

================================== =//=//= Altair Realty =//=//= -=-=-=- Properties Listing -=-=-=---------------------------------Property #: 4LP804 Property Type: SingleFamily Stories: 3 Has Indoor Car Garage: True Finished Basement: False Condition: NeedsRepair Bedrooms: 4 Bathrooms: 2.5 Year Built: 1996 Market Value: $640,885.80 Press any key to continue . . .

9. Close the DOS window and return to your programming environment

C# 3.0 Practical Learning

329

Implementation of Derived Members
You can notice in the above example that the derived class produces the same results as the base class. In reality, inheritance is used to solve various Object-Oriented Programming (OOP) problems. One of them consists of customizing, adapting, or improving the behavior of a feature (property or method, etc) of the parent class. For example, although both the circle and the sphere have an area, their areas are not the same. A circle is a flat surface but a sphere is a volume, which makes its area very much higher. Since they use different formulas for their respective area, you should implement a new version of the area in the sphere. Based on this, when deriving your class from another class, you should be aware of the properties and methods of the base class so that, if you know that the parent class has a certain behavior or a characteristic that is not conform to the new derived class, you can do something about that. A new version of the area in the sphere can be calculated as follows:
using System; class Circle { private double _radius; public double Radius { get { if( _radius < 0 ) return 0.00; else return _radius; } set { _radius = value; } }

C# 3.0 Practical Learning

330

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 { public double Area { get { return 4 * Radius * Radius * 3.14159; } } } class Exercise { public static int Main() { var Round = new Circle(); Round.Radius = 25.55; Console.WriteLine("Circle Characteristics"); Console.WriteLine("Side: {0}", Round.Radius); Console.WriteLine("Diameter: {0}", Round.Diameter); Console.WriteLine("Circumference: {0}", Round.Circumference); Console.WriteLine("Area: {0}", Round.Area); var Ball = new Sphere(); Ball.Radius = 25.55; Console.WriteLine("\nSphere Characteristics"); Console.WriteLine("Side: {0}", Ball.Radius); Console.WriteLine("Diameter: {0}", Ball.Diameter); Console.WriteLine("Circumference: {0}", Ball.Circumference); Console.WriteLine("Area: {0}", Ball.Area); return 0; }

C# 3.0 Practical Learning

331

}

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: 8203.3512239 Press any key to continue

Notice that, this time, the areas of both figures are not the same even though their radii are similar. Besides customizing member variables and methods of a parent class, you can add new members as you wish. This is another valuable feature of inheritance. In our example, while the is a flat shape, a sphere has a volume. In this case, you may need to calculate the volume of a sphere as a new method or property of the derived class. 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; }

C# 3.0 Practical Learning

332

}

} public double Area { get { return Radius * Radius * 3.14159; } }

class Sphere : Circle { public double Area { get { return 4 * Radius * Radius * 3.14159; } } public double Volume { get { return 4 * 3.14159 * Radius * Radius * Radius / 3; } } } class Exercise { public static int Main() { var Round = new Circle(); Round.Radius = 25.55; Console.WriteLine("Circle Characteristics"); Console.WriteLine("Side: {0}", Round.Radius); Console.WriteLine("Diameter: {0}", Round.Diameter); Console.WriteLine("Circumference: {0}", Round.Circumference); Console.WriteLine("Area: {0}", Round.Area); var Ball = new Sphere(); Ball.Radius = 25.55; Console.WriteLine("\nSphere Characteristics"); Console.WriteLine("Side: {0}", Ball.Radius); Console.WriteLine("Diameter: {0}", Ball.Diameter); Console.WriteLine("Circumference: {0}", Ball.Circumference); Console.WriteLine("Area: {0}", Ball.Area); Console.WriteLine("Volume: {0}\n", Ball.Volume); return 0; } }

This would produce:
Circle Characteristics Side: 25.55

C# 3.0 Practical Learning

333

Diameter: 51.1 Circumference: 160.535249 Area: 2050.837805975 Sphere Characteristics Side: 25.55 Diameter: 51.1 Circumference: 160.535249 Area: 8203.3512239 Volume: 209595.623770645 Press any key to continue

If you create a property or method in a derived class and that property or method already exists in the parent class, when you access the property or method in the derived class, you must make sure you indicate what member you are accessing. To make this possible, the C# language provides the base keyword. To access a property or method of a parent class from the derived class, type the base keyword, followed by the period operator, followed by the name of the property or method of the base class.

The new Modifier
Imagine you create a class used to process a circle as we saw earlier. You can use this as the base class for a sphere. Both the circle and the sphere have an area but their values are different. This means that, as mentioned in our introduction to inheritance, when deriving the sphere class, you would have to calculate a new area for the cube. If you create or declare a new member in a derived class and that member has the same name as a member of the base class, when creating the new member, you may want to indicate to the compiler that, instead of overriding that same method that was defined in the base class, you want to create a brand new and independent version of that method. When doing this, you would be asking the compiler to hide the member of the base class that has the same name, when the member of the current class is invoked. To do this, type the new keyword to its left. Here is an example:
using System; class Circle { private double _radius; public double Radius { get { return (_radius < 0) ? 0.00 : _radius; } set { _radius = value; } } public double Diameter { get { return Radius * 2; } } public double Circumference {

C# 3.0 Practical Learning

334

get }

{ return Diameter * 3.14159; }

public double Area { get { return Radius * Radius * 3.14159; } } } class Sphere : Circle { new public double Area { get { return 4 * Radius * Radius * 3.14159; } } public double Volume { get { return 4 * 3.14159 * Radius * Radius * Radius / 3; } }

}

class Exercise { public static int Main() { var Round = new Circle(); Round.Radius = 25.55; Console.WriteLine("Circle Characteristics"); Console.WriteLine("Side: {0}", Round.Radius); Console.WriteLine("Diameter: {0}", Round.Diameter); Console.WriteLine("Circumference: {0}", Round.Circumference); Console.WriteLine("Area: {0}", Round.Area); var Ball = new Sphere(); Ball.Radius = 25.55; Console.WriteLine("\nSphere Characteristics"); Console.WriteLine("Side: {0}", Ball.Radius); Console.WriteLine("Diameter: {0}", Ball.Diameter); Console.WriteLine("Circumference: {0}", Ball.Circumference); Console.WriteLine("Area: {0}", Ball.Area); Console.WriteLine("Volume: {0}\n", Ball.Volume); } } return 0;

C# 3.0 Practical Learning

335

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"; } 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; } }

} }

C# 3.0 Practical Learning

336

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 class 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 with the period operator. Here is an example:
Source File: Exercise.cs using System; class Exercise { public static int Main() { People.Person man = new People.Person("Hermine Sandt", "Male"); HighSchool.Teacher staff = new HighSchool.Teacher("Vice Principal"); Console.WriteLine(); return 0;

} }

C# 3.0 Practical Learning

337

Alternatively, 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 { public static int Main() { Person man = new Person("Hermine Sandt", "Male"); Teacher staff = new Teacher("Vice Principal"); Console.WriteLine(); return 0; } }

Practical Learning: Using Inheritance With Namespaces
1. Start Microsoft Visual C# and create a Console Application named
Geometry2

2. To create a new class, on the main menu, click Project -> Add Class... 3. Set the Name to Square and press Enter 4. Change the file as follows:
using System; namespace Geometry2 { public class Square { private double _side; public Square() { _side = 0.00; } public Square(double s) { _side = s; }

} }

5. To create a new class, on the main menu, click Project -> Add Class... 6. Set the Name to Rectangle and press Enter C# 3.0 Practical Learning
338

7. Change the file as follows:
using System; namespace Geometry2 { public class Rectangle { double _length; double _height; public Rectangle() { _length = 0.00; _height = 0.00; } public Rectangle(double L, double H) { _length = L; _height = H; }

} }

8. Save all

Protected Members
To maintain a privileged relationship with its children, a parent class can make a member 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. Here are examples:
Source File: Persons.cs using System; public class Person { private string _name; private string _gdr; public Person() { this._name = "Not Available"; this._gdr = "Unknown"; } public Person(string name, string gender) { this._name = name; this._gdr = gender; } protected string FullName

C# 3.0 Practical Learning

339

{ 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 { public static int Main() { People.Person man = new People.Person("Hermine Sandt", "Male"); Console.WriteLine("Staff Member"); man.Show(); Console.WriteLine(); return 0; } }

This would produce:
Staff Member Full Name: Hermine Sandt Gender: Male

If you create a class member and mark it as protected, the classes derived of its parent class, created in the current program or outside the current program, can access it. If you want the member to be accessed only by derived classes implemented in the same program but not derived classes implemented outside of the current program, mark the member as protected internal. Here are examples:
Source File: Persons.cs using System; public class Person { private string _name; private string _gdr;

C# 3.0 Practical Learning

340

public Person() { this._name = "Not Available"; this._gdr = "Unknown"; } public Person(string name, string gender) { this._name = name; this._gdr = gender; } protected internal string FullName { get { return _name; } set { _name = value; } } protected internal string Gender { get { return _gdr; } set { _gdr = value; } } public void Show() { Console.WriteLine("Full Name: {0}", this.FullName); Console.WriteLine("Gender: {0}", this.Gender); } }

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 or a method that already exists in the base class, you should let the compiler know that you are providing a new version. In both cases, the common member should be created as virtual. To create a virtual member, 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 {

C# 3.0 Practical Learning

341

return Radius * Radius * 3.14159; } } }

In Microsoft Visual C#, unlike C++, if you omit the virtual keyword, the (Microsoft Visual C#) compiler would display a warning. When you derive a class from an abstract class, 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; } } 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. To create a new class, on the main menu, click Project -> Add Class... 2. Set the Name to a ShapeDescription and press Enter 3. Change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry2 { public class ShapeDescription { public virtual string Description() {

C# 3.0 Practical Learning

342

string Msg = "A quadrilateral is a geometric figure " + "that has four sides and four angles."; return Msg; } } }

4. Save the file as Quadrilaterals.cs in the Shapes1 folder 5. Access the Square.cs file and override the Description method as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry2 { public 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() + "\nA square is a quadrilateral that has four " + "equal sides and four right angles"; return Introduction; } } }

6. Access Rectangle.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry2 { public class Rectangle : ShapeDescription { double _length; double _height;

C# 3.0 Practical Learning

343

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; } } }

+

7. Access the Program.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

class Exercise { static void DisplaySquare(Square S) { Console.WriteLine("Square Characteristics"); Console.WriteLine("Description: {0}", S.Description()); } static void DisplayRectangle(Rectangle R) { Console.WriteLine("Rectangle Characteristics"); Console.WriteLine("Description: {0}", R.Description()); } static void Main() { Square Sq = new Square(); Rectangle Rect = new Rectangle(); Console.WriteLine("========================================"); DisplaySquare(Sq); Console.WriteLine("========================================"); DisplayRectangle(Rect); Console.WriteLine("========================================");

C# 3.0 Practical Learning

344

} }

Console.WriteLine();

8. Execute the project. 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. ========================================

9. Close the DOS window

Abstract Classes
In a program, 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. Such a class is referred to as abstract. Therefore, an abstract class can be created only to serve as a parent class for other classes. To create an abstract class, type the abstract keyword to the left of its name. Here is an example:
abstract class Ball { protected int TypeOfSport; protected string Dimensions; }

Practical Learning: Creating an Abstract Class
1. To create an abstract class, access the ShapeDescription.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry2 { public abstract class ShapeDescription { public virtual string Description() {

C# 3.0 Practical Learning

345

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 a 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 ShapeDescription.cs file and change its class as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry2 { public abstract class ShapeDescription { public abstract string Name { get; } public virtual string Description() { string Msg = "A quadrilateral is a geometric figure " +

C# 3.0 Practical Learning

346

"that has four sides and four angles."; } } } return Msg;

2. Access the Square.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry2 { public 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() + "\nA square is a quadrilateral that has four " + "equal sides and four right angles"; return Introduction;

} } }

3. Access the Rectangle.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry2 { public class Rectangle : ShapeDescription {

C# 3.0 Practical Learning

347

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 { 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. Access the Program.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry2 { public class Program { static void DisplaySquare(Square S) { Console.WriteLine("Square Characteristics"); Console.WriteLine("Name: {0}", S.Name); Console.WriteLine("Description: {0}", S.Description()); } static void DisplayRectangle(Rectangle R) { Console.WriteLine("Rectangle Characteristics"); Console.WriteLine("Name: {0}", R.Name); Console.WriteLine("Description: {0}", R.Description());

C# 3.0 Practical Learning

348

} 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(); } }

5. Execute the project. 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 angles ======================================== 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 implies that its four angles are right. ========================================

6. Close the DOS window

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 the left of the class keyword. Here is an example:
public sealed class Ball { public int TypeOfSport; public string Dimensions; }

There is not much to do about a sealed class. Simply remember that no class can be derived from it. 349 C# 3.0 Practical Learning

Interfaces
Introduction
Imagine you start creating a class and, while implementing or testing it, you find out that this particular class can be used 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. On the main menu, click Project -> Add New Item... 2. In the Templates list, click Interface 3. Set the Name to Quadrilateral and click Add 4. Change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry2 { interface IQuadrilateral { } }

5. 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: C# 3.0 Practical Learning
350

You can indicate that it would be read-only by adding an empty getter property to it. Here is an example:

public interface ICourtDimensions { double Length { get; } }

You can indicate that it would be write-only by adding an empty setter property to it. 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. To provide this information, add a getter and a setter accessories to it. Here is an example:

public interface ICourtDimensions { double Length { get; set; } }

In the same way, you can create as many properties as you judge 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 property, change the file as follows:
using System; using System.Collections.Generic; using System.Linq;

C# 3.0 Practical Learning

351

using System.Text; namespace Geometry2 { interface IQuadrilateral { double Area { get; } } }

2. Save the file

An Interface as a Base Class
An interface is used to lay a foundation for other classes. For this reason, it is the prime 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
C# 3.0 Practical Learning
352

1. On the main menu, click Project -> Add New Item... 2. In the Templates list, click Interface 3. Set the Name to RightAngle and click Add 4. Change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry2 { interface IRightAngle : IQuadrilateral { double Base { get; set; } double Height { get; set; } double Perimeter { get; } } }

5. Access the Square.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry2 { public class Square : ShapeDescription, IRightAngle { . . . } }

6. Access the Rectangle.cs file and change it as follows:
using System; namespace Geometry2 { public class Rectangle : ShapeDescription, IRightAngle { . . . } }

7. Save all

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 C# 3.0 Practical Learning
353

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 methods, 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 { 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 were 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 parental 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 {

C# 3.0 Practical Learning

354

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 { 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

C# 3.0 Practical Learning

355

{ public static int 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(); return 0; } }

This would produce:
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. Access the Square.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry2 { public class Square : ShapeDescription, IRightAngle { private double _side; public Square() { _side = 0.00; }

C# 3.0 Practical Learning

356

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 { 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; } } } }

2. Access the Rectangle.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry2 { public class Rectangle : ShapeDescription, IRightAngle { double _length; double _height; public Rectangle()

C# 3.0 Practical Learning

357

{ _length = 0.00; _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;

}

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); } } } }

3. Access the Program.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

C# 3.0 Practical Learning

358

namespace Geometry2 { public class Program { static Square CreateASquare() { double side; Console.Write("Enter the side of the square: "); side = double.Parse(Console.ReadLine()); Square Sqr = new Square(side); return Sqr; } static void DisplaySquare(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 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()); Rectangle Recto = new Rectangle(Len, Hgt); return Recto;

}

static void DisplayRectangle(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); Console.WriteLine("Perimeter: {0}", R.Perimeter); Console.WriteLine("Area: {0}", R.Area); } static int Main() { Square Sq = new Square(); Rectangle Rect = new Rectangle(); Sq = CreateASquare(); Rect = CreateARectangle();

C# 3.0 Practical Learning

359

Console.WriteLine("============================"); DisplaySquare(Sq); Console.WriteLine("============================"); DisplayRectangle(Rect); Console.WriteLine("============================"); Console.WriteLine(); return 0;

} } }

4. Execute the application and test it. Here is an example:
Enter the side of the square: 44.16 Enter the dimensions of the rectangle Base: 58.62 Height: 36.06 ============================ 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 angles ---------------------------Side: 44.16 Perimeter: 176.64 Area: 1950.1056 ============================ 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 implies that its four angles are right. ---------------------------Base: 58.62 Height: 36.06 Perimeter: 189.36 Area: 2113.8372 ============================ Press any key to continue . . .

5. Close the DOS window

Class Partial Implementation
In all of the classes we have defined so far, we were using a single file to implement the class. In C#, you can create a class (the same class) in different files. This means that you can start a class in one file and continue it in another file or in other files. This is referred to as partial implementation. If you have programmed in C++ or C++/CLI, don't confuse its header and source files with C#'s partial implementation of classes. In C++ or C++/CLI, you can include the structure of a class with its member C# 3.0 Practical Learning
360

variables (called fields in C#) and the declaration of its methods. In C+ +, a header file has the extension .h. Here is an example of a C++/CLI header file:
Header File: Cylinder.h #pragma once using namespace System; public ref class CCylinder { private: double rad; double hgt; public: CCylinder(void); CCylinder(double radius, double height); property double Radius { double get() { return rad; } void set(double value) { rad = value; } } property double Height { double get() { return hgt; } void set(double value) { hgt = value; } } double Volume(); };

In C++, after creating a header file, you can create its associated source file. The source file has the extention .cpp. Here is an example of the source file corresponding to the above header file:
Source File: Cylinder.cpp #include "Cylinder.h" CCylinder::CCylinder(void) : rad(0.00), hgt(0.00) { } CCylinder::CCylinder(double radius, double height) : rad(radius), hgt(height) { } double CCylinder::Volume() { return rad * rad * hgt * Math::PI; }

C# 3.0 Practical Learning

361

The above class can be tested with the following:
Source File: Exercise.cpp #include "Cylinder.h" using namespace System; CCylinder ^ Initialize() { CCylinder ^ c = gcnew CCylinder(36.12, 18.84); return c; } const void Show(CCylinder ^ vol) { Console::WriteLine(L"Radius: {0}", vol->Radius); Console::WriteLine(L"Height: {0}", vol->Height); Console::WriteLine(L"Volume: {0}", vol->Volume()); } int main() { CCylinder ^ cyl = Initialize(); Show(cyl); return 0; }

As we have seen so far, in C#, you cannot simply and only declare a method in a file for a forward (later) implementation, as it's done in C, C++, C++/CLI, and (Object) Pascal. In C#, to create a class in various classes, start the class in one file but precede the class keyword with partial. Here is an example of a file named first.cs that contains some (2) private fields and some (2) properties:
Source File: geometry1.cs using System; partial class Cylinder { private double rad; private double hgt; public Cylinder(double radius, double height) { this.rad = radius; this.hgt = height; } public double Radius { get { return rad; } set { rad = value; } }

C# 3.0 Practical Learning

362

public double Height { get { return hgt; } set { hgt = value; } } }

After creating the class in one file, you can use as any of the classes as we have done so far. Here is an example:
Source File: Exercise.cs using System; class Program { static Cylinder Initialize() { Cylinder c = new Cylinder(36.12, 18.84); return c; } static void Show(Cylinder vol) { Console.WriteLine("Radius: {0}", vol.Radius); Console.WriteLine("Height: {0}", vol.Height); } static int Main() { Cylinder cyl = Initialize(); Show(cyl); Console.WriteLine(); return 0; } }

This would produce:
Radius: 36.12 Height: 18.84 Press any key to continue . . .

If you had created a partial class, or you got a partial class from somebody (not as part of a DLL or nor from another type of library), and you find out that the class is not complete, you can then complement it. One of the rules you must observe is that the partial class must have been marked as partial, as we did above. One of the advantages of partial implementation is that you don't have to get back to the first or previous file to modify it in order to complement the class. You can simply start another file and continue the class in it. Two other rules you must observe are that you must use the same name for the class and you must precede the class keyword with partial. Here is an example:
Source File: geometry2.cs using System;

C# 3.0 Practical Learning

363

partial class Cylinder { public Cylinder() { this.rad = 0.00; this.hgt = 0.00; } public double Volume() { return rad * rad * hgt * Math.PI; } }

This class can then be tested as follows:
Source File: Exercise.cs using System; class Program { static Cylinder Initialize() { Cylinder c = new Cylinder(); c.Radius = 42.66; c.Height = 26.48; return c; } static void Show(Cylinder vol) { Console.WriteLine("Radius: {0}", vol.Radius); Console.WriteLine("Height: {0}", vol.Height); Console.WriteLine("Volume: {0}", vol.Volume()); } static int Main() { Cylinder cyl = Initialize(); Show(cyl); Console.WriteLine(); return 0;

} }

This would produce:
Radius: 42.66 Height: 26.48 Volume: 151394.310951986 Press any key to continue . . .

C# 3.0 Practical Learning

364

Once a partial class has been created, you can create another based on it. The child class doesn't have to be partial, although it can be.

Practical Learning: Partially Implementing a Class
1. Start Microsoft Visual C# and create a Console Application named
Geometry3

2. To add a new source file, on the main menu, click Project -> Add New Item... 3. In the Templates list, click Code File 4. Set the Name to circle1 and click Add 5. Change the file as follows:
public partial class Circle { private double _radius; public double Radius { get { return (this._radius <= 0) ? 0.00 : this._radius; } set { this._radius = value; } } public double Diameter { get { return this.Radius * 2; } } public double Circumference { get { return Diameter * 3.14159; } } public double Area { get { return this.Radius * this.Radius * 3.14159; } }

}

6. To create a new source file, in the Solution Explorer, right-click Geometry3 -> Add -> New Item... 7. In the Templates list, make sure Code File is selected; otherwise, click it. Set the Name to circle2 and click Add 8. Change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

public partial class Circle

C# 3.0 Practical Learning

365

{ public Circle() { this.Radius = 0.00; } public Circle(double radius) { this.Radius = radius; } public void Present() { Console.WriteLine("Radius: Console.WriteLine("Diameter: Console.WriteLine("Circumference: Console.WriteLine("Area: }

{0}", {0}", {0}", {0}",

this.Radius); this.Diameter); this.Circumference); this.Area);

}

9. To test the class, access the Program.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry3 { class Program { static Circle Initialize() { Console.Write("Enter the radius: "); double rad = double.Parse(Console.ReadLine()); Circle c = new Circle(rad); return c; } static int Main() { Console.WriteLine( "This application allows you to process a circle"); Circle circ = Initialize(); Console.WriteLine("\n=============================="); Console.WriteLine("Circle Characteristics"); Console.WriteLine("------------------------------"); circ.Present(); Console.WriteLine("==============================\n"); } } } return 0;

10.

Execute the application to sew the result. Here is an example: C# 3.0 Practical Learning
366

This application allows you to process a circle Enter the radius: 10.08 ============================== Circle Characteristics -----------------------------Radius: 10.08 Diameter: 20.16 Circumference: 63.3344544 Area: 319.205650176 ============================== Press any key to continue . . .

11. Return to your programming environment 12. To create a new source file, on the main menu, click Project -> Add New Item... 13. In the Templates list, make sure Code File is selected; otherwise, click it. Set the Name to cylinder1 and press Enter 14.
using using using using

Change the file as follows:
System; System.Collections.Generic; System.Linq; System.Text;

public partial class Cylinder : Circle { private double hgt; public double Height { get { return (this.hgt <= 0) ? 0.00 : this.hgt; } set { this.hgt = value; } } public double LateralArea { get { return this.Circumference * Height; } } public double TotalArea { get { return this.Area + this.LateralArea; } } public double Volume { get { return this.Radius * this.Radius * this.Height * Math.PI; } }

}

C# 3.0 Practical Learning

367

15. To create a new source file, in the Solution Explorer, right- click Geometry3 -> Add -> New Item... 16. In the Templates list, make sure Code File is selected; otherwise, click it. Set the Name to cylindder2 and click Add 17.
using using using using

Change the file as follows:
System; System.Collections.Generic; System.Linq; System.Text;

public partial class Cylinder : Circle { // This is the default constructor of the cylinder // This constructor assumes that we don't have any dimension public Cylinder() { this.Radius = 0.00; } // This constructor assumes that there exists a radius // The radius could have been specified on a parent circle public Cylinder(double height) { this.Height = height; } // This constructor can be used to specify both // the radius of the base and the height of the volume // The radius can also have been defined by a parent circle public Cylinder(double radius, double height) { this.Radius = radius; this.Height = height; } new public void Present() { Console.WriteLine("Height: Console.WriteLine("Lateral Area: Console.WriteLine("Total Area: Console.WriteLine("Volume: } }

{0}", {0}", {0}", {0}",

this.Height); this.LateralArea); this.TotalArea); this.Volume);

18. To test the class, access the Program.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Geometry3 { class Program

C# 3.0 Practical Learning

368

{ static Circle Initialize() { Console.Write("Enter the radius: "); double rad = double.Parse(Console.ReadLine()); Circle c = new Circle(rad); return c;

}

static double GetHeight() { Console.Write("Enter the height: "); double hgt = double.Parse(Console.ReadLine()); } return hgt;

static int Main() { Console.WriteLine( "This application allows you to process a cylinder"); Circle circ = Initialize(); double height = GetHeight(); Cylinder cldr = new Cylinder(circ.Radius, height); Console.WriteLine("\n================================"); Console.WriteLine("=//=Cylinder Characteristics=//="); Console.WriteLine("================================"); Console.WriteLine(" =-= Base Characteristics =-="); Console.WriteLine("--------------------------------"); circ.Present(); Console.WriteLine("------------------------------"); Console.WriteLine("=-= Volume Characteristics =-="); cldr.Present(); Console.WriteLine("================================\n"); } } } return 0;

19.

Execute the application to sew the result. Here is an example:

This application allows you to process a cylinder Enter the radius: 85.15 Enter the height: 44.95 ================================ =//=Cylinder Characteristics=//= ================================ =-= Base Characteristics =-= -------------------------------Radius: 85.15 Diameter: 170.3 Circumference: 535.012777 Area: 22778.168980775 -----------------------------=-= Volume Characteristics =-=

C# 3.0 Practical Learning

369

Height: 44.95 Lateral Area: 24048.82432615 Total Area: 46826.993306925 Volume: 1023879.5605199 ================================ Press any key to continue . . .

20.

Return to your programming environment

C# 3.0 Practical Learning

370

Delegates and Events
Fundamentals of Delegates
Introduction
The C and C++ languages have long used 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. 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 Microsoft Visual C# and create a Console Application named
WattsALoan1

2. To create a new class, on the main menu, click Project -> Add Class... 3. Change the name of the file to LoanEvaluation and click Add 4. Change the contents of the file as follows:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace WattsALoan1 { public class LoanEvaluation { public double GetPrincipal()

C# 3.0 Practical Learning

371

{ Console.Write("Enter the Principal: $"); double P = double.Parse(Console.ReadLine()); return P; } public double GetInterestRate() { Console.Write("Enter the Interest Rate (%): "); double r = double.Parse(Console.ReadLine()); return r; } public int GetPeriod() { Console.Write("Enter the number of months: int t = int.Parse(Console.ReadLine()); return t; } } }

");

5. Access the Program.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace WattsALoan1 { public class Program { static int Main() { int NumberOfPeriods; double Principal, IntRate; LoanEvaluation loan = new LoanEvaluation(); Console.WriteLine( "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %"); Console.WriteLine("Loan Processing\n"); 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"); Principal = loan.GetPrincipal(); IntRate = loan.GetInterestRate(); NumberOfPeriods = loan.GetPeriod(); Console.WriteLine( "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

");

%\n");

C# 3.0 Practical Learning

372

Console.WriteLine("================================"); Console.WriteLine("Loan Estimation"); 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; } } }

6. Execute the application test it. Here is an example:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Loan Processing This program allows you to calculate the amount of money a customer will owe at the end of the lifetime of a loan Enter the Principal: $14500 Enter the Interest Rate (%): 12.25 Enter the number of months: 48 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ================================ Loan Estimation -------------------------------Principal: $14,500.00 Interest: 12.25 % Period: 48 months ================================ Press any key to continue . . .

7. Close the DOS window 8. 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. Access the LoanProcecssing.cs file and change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace WattsALoan1 { class LoanEvaluation { public double GetPrincipal()

C# 3.0 Practical Learning

373

{ Console.Write("Enter the Principal: $"); double P = double.Parse(Console.ReadLine()); return P; } public double GetInterestRate() { Console.Write("Enter the Interest Rate (%): "); double r = double.Parse(Console.ReadLine()); return r; } public void GetPeriod(ref int TypeOfPeriod, ref int Periods) { Console.WriteLine("How do you want to enter the length of 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 } } } } Console.WriteLine("Bad Selection\n");

time?");

up

9. Access the Program.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace WattsALoan1

C# 3.0 Practical Learning

374

{ public class Program { static int Main() { int Periods = 0; int TypeOfPeriod = 0; double Principal, IntRate; string PeriodName = null; LoanEvaluation loan = new LoanEvaluation(); Console.WriteLine( "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"); 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("Loan Processing\n"); Principal = loan.GetPrincipal(); IntRate = loan.GetInterestRate(); loan.GetPeriod(ref TypeOfPeriod, ref Periods); if (TypeOfPeriod == 0) { // Since the user made a bad selection, stop the program return 0; }// Since this "if" condition has a "return 0" line, if the "if" of would an // condition produces true, the "return 0" means the function // would be terminated. If the condition is false, the inside // this "if" condition would not execute and the function // continue. This means that, if the condition is false, then // the "else' is implied. Therefore, we don't have to write // "else" condition: it is automatic. if (TypeOfPeriod == 1) { PeriodName = "days"; } else if (TypeOfPeriod == 2) { PeriodName = "months"; } else if (TypeOfPeriod == 3) { PeriodName = "years"; } Console.WriteLine( "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"); Console.WriteLine("=================================="); Console.WriteLine("Loan Estimation"); Console.WriteLine("----------------------------------"); Console.WriteLine("Principal: {0:C}", Principal);

here

C# 3.0 Practical Learning

375

Console.WriteLine("Interest: {0:P}", IntRate / 100); Console.WriteLine("Period: {0} {1}", Periods, PeriodName); Console.WriteLine("==================================\n"); return 0; } } }

10.

Execute the application and test it. 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: $7500.00 Enter the Interest Rate (%): 8.75 How do you want to enter the length of time? 1 - In Days 2 - In Months 3 - In Years Your Choice: 3 Enter the number of years: 4 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ================================== Loan Estimation ---------------------------------Principal: $7,500.00 Interest: 8.75 % Period: 4 years ================================== Press any key to continue . . .

11.

Close the DOS window

Creating a Delegate
To create a delegate, you use the delegate keyword. The basic formula used to create a delegate is:
[attributes] [modifiers] delegate ReturnType Name ([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 C# name. C# 3.0 Practical Learning
376

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, leave the parentheses empty. Here is an example:
using System; public delegate void Simple(); public class Program { static int Main() { return 0; } }

After declaring a delegate, 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 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 corresponding method as follows:
public delegate void Simple(); public class Exercise { public void Welcome() { Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); } }

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, declare a variable of the type of the delegate and assign the method to the delegate variable. Because you are assigning the method to a delegate, one of the rules of delegates is that you must not apply the parentheses to the method. Here is an example
public class Program { static int Main() { Exercise exo = new Exercise(); Simple msg = exo.Welcome; return 0; } }

Accessing a Delegate
C# 3.0 Practical Learning
377

Introduction
Once you have assigned a method to a delegate variable, you can you the delegate variable as if it were a defined method. That is, you can call as you would a normal method. Here is an example:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

public delegate void Simple(); public class Exercise { public void Welcome() { Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); } } namespace Delegates { public class Program { static int Main() { Exercise exo = new Exercise(); Simple msg = exo.Welcome; msg(); return 0; } } }

This would produce:
Welcome to the Wonderful World of C# Programming! Press any key to continue . . .

A Static Method for a Delegate
In the above example, we had to declare a variable of the (Exercise) class before accessing the method. An alternative is to create the associated method as static. That way, you would not need to declare the variable first. Here is an example:
using System; public delegate void Simple(); public class Exercise { public static void Welcome()

C# 3.0 Practical Learning

378

{ Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); } } public class Program { static int Main() { Simple msg = Exercise.Welcome; msg(); return 0; } }

An Anonymous Delegate
In the above examples, we had to create a method that would be associated with a delegate. You can create a delegate, then, when you need to use, create a type of local implementation of a method and use it. In other words, you do not have to explicitly define a method prior to using the delegate. Such a method is referred to as anymous. Before implementing an anonymous method, first declare the delegate you will use:
using System; public delegate void Simple(); public class Program { static int Main() { return 0; } }

To create an anonymous method, declare a variable for the delegate and assign it the delegate keyword as if it were a method. That is, followed by parentheses and curly brackets that would represent the body of the method. In the body of the anonymous method, do whatever you want. Here is an example:
using System; public delegate void Simple(); public class Program { static int Main() { Simple msg = delegate() {

C# 3.0 Practical Learning

379

Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); }; return 0; } }

Once you have done this, you can then call the delegate variable as if it were a normal method. Here is an example:
using System; public delegate void Simple(); public class Program { static int Main() { Simple msg = delegate() { Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); }; msg(); } } return 0;

The Lambda Operator
You can also create an anonymous method using an operator called lambda and represented by =>. From our example above, to use the lambda operator to create an anonymous method, omit the delegate keyword and follow the parentheses by the operator. Here is an example:
using System; public delegate void Simple(); public class Program { static int Main() { Simple msg = () => { Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); }; return 0; } }

Once you have done this, you can call the delegate variable as a method. Here is an example: C# 3.0 Practical Learning
380

using System; public delegate void Simple(); public class Program { static int Main() { Simple msg = () => { Console.WriteLine("Welcome to the Wonderful World of C# Programming!"); }; msg(); return 0; } }

A Delegate that Returns a Value
You can create a delegate that returns a value. When creating the delegate, specify the data type to the left side of the name of the delegate. When defining a method that would be associated with the delegate, remember that the method must return the same type of value. In the body of the method, use it as you see fit. Before exiting the method, make sure you appropriately return a value. To use the method, follow the same approach as above. This time, when calling the delegate variable, you should use the parentheses. Here is an example:
using System; delegate double Doubler(); public class Exercise { public static double MultiplyBy2() { return 255 * 2; } } public class Program { static int Main() { Doubler By2 = Exercise.MultiplyBy2; Console.WriteLine("Number = {0}", By2()); } } return 0;

This would produce: C# 3.0 Practical Learning
381

Number = 510 Press any key to continue . . .

In the same way, you can create an anonymous method that implements the delegate. To do this, follow the same rule we defined earlier. For example, you can use the delegate keyword. Here is an example:
using System; delegate double Doubler(); public class Program { static int Main() { Doubler By2 = delegate() { return 255 * 2; }; Console.WriteLine("Number = {0}", By2()); } } return 0;

Or you can use the lambda operator:
using System; delegate double Doubler(); public class Program { static int Main() { Doubler By2 = () => { return 255 * 2; }; Console.WriteLine("Number = {0}", By2()); } } return 0;

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
C# 3.0 Practical Learning
382

Introduction
If you want to use a method that takes arguments and associate it 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 Doubler(double x);

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:
public class Algebra { public static double MultiplyBy2(double a) { return a * 2; } }

Using an Argumentative Delegate
To associate the method to the delegate, you can declare a variable for the delegate and assign the name of the method to it. Here is an example:
using System; delegate double Doubler(double x); public class Algebra { public static double MultiplyBy2(double a) { return a * 2; } } public class Program { static int Main() { Doubler dbl = Algebra.MultiplyBy2; Console.WriteLine("Result = {0}", dbl); } } return 0;

Notice that only the name of the method is passed to the delegate. To actually use the delegate, when calling it, add the parentheses to it and in the parentheses, provide a value for the argument(s). Here is an example:
using System; delegate double Doubler(double x);

C# 3.0 Practical Learning

383

public class Algebra { public static double MultiplyBy2(double a) { return a * 2; } } public class Program { static int Main() { Doubler dbl = Algebra.MultiplyBy2; Console.WriteLine("Result = {0}", dbl(248)); return 0; } }

This would produce:
Result = 496 Press any key to continue . . .

A Lambda Expression
You can create an anonymous method for a delegate that takes one or more arguments. You can do this using the delegate keyword. In its parentheses, pass an argument that is the same type as the argument of the delegate. Then, in the body of the method, do what you judge necessary. When calling the variable of the delegate, use the same rules we have applied so far. Here is an example:
using System; delegate double Doubler(double x); public class Program { static int Main() { Doubler dbl = delegate(double alpha) { return alpha * 2; }; Console.WriteLine("Result = {0}", dbl(248)); return 0; } }

This technique of using the delegate keyword was introduced in C# 2.0 and has been updated with the lambda operator. Therefore, this was probably the last time we use it since we have been able to apply to different types of delegates. C# 3.0 Practical Learning
384

Instead of the delegate keyword, you can define an anonymous method using the lambda operator. In this case, in the parentheses of the lambda expression, enter the data type of the argument followed by its name. Here is an example:
using System; delegate double Doubler(double x); public class Program { static int Main() { Doubler dbl = (double alpha) => { }; return 0; } }

In the body of the anonymous method, use the argument as you see fit. Here is an example:
using System; delegate double Doubler(double x); public class Program { static int Main() { Doubler dbl = (double alpha) => { return alpha * 2; }; return 0; } }

After defining the method, you can call it like a normal method. Here is an example:
using System; delegate double Doubler(double x); public class Program { static int Main() { Doubler dbl = (double alpha) => { return alpha * 2; }; Console.WriteLine("Result = {0}", dbl(248)); return 0;

C# 3.0 Practical Learning

385

} }

In our example, we specified the type of the argument. If you want, you can let the compiler figure out the type of argument. In this case, pass only the name of the argument and not its type. Here is an example:
using System; delegate double Doubler(double x); public class Program { static int Main() { Doubler dbl = (alpha) => { return alpha * 2; }; Console.WriteLine("Result = {0}", dbl(248)); } } return 0;

A Delegate With Many Arguments
A delegate can take more than one argument. To start, when declaring it, pass the desired number of arguments. If you will use a method to associate to the delegate, then create the method also. Here is an example:
delegate double Addition(double x, double y); public class Algebra { public static double Plus(double a, double b) { return a + b; } }

To use the delegate, follow the techniques we have applied so far and call the delegate as a method. Here is an example:
using System; delegate double Addition(double x, double y); public class Algebra { public static double Plus(double a, double b) { return a + b; } } public class Exercise {

C# 3.0 Practical Learning

386

static int Main() { Addition Operation = Algebra.Plus; Console.WriteLine("Result = {0}", Operation(52.04, 9.368)); return 0; } }

This would produce:
Result = 61.408 Press any key to continue . . .

If you want to use a lambda expression to create an anonymous method, in its parentheses, pass the right number of arguments. In the body of the anonymous method, use the arguments ad you see fit. To use the delegate, call it as you would a normal method. Here is an example:
using System; delegate double Addition(double x, double y); public class Exercise { static int Main() { Addition Operation = (x, y) => { return x + y; }; Console.WriteLine("Result = {0}", Operation(52.04, 9.368)); return 0; } }

Practical Learning: Passing Arguments to a Delegate
1. Access the LoanEvaluation.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace WattsALoan1 { public class LoanEvaluation { public double GetPrincipal() { Console.Write("Enter the Principal: $"); double P = double.Parse(Console.ReadLine());

C# 3.0 Practical Learning

387

}

return P;

public double GetInterestRate() { Console.Write("Enter the Interest Rate (%): "); double r = double.Parse(Console.ReadLine()); } return r;

public double GetPeriod(ref int TypeOfPeriod, ref double 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 = 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: "); Periods = double.Parse(Console.ReadLine()); return Periods; } else { TypeOfPeriod = 0; // The user made an invalid selection. So, we will give Console.WriteLine("Bad Selection\n"); return 0.00; } }

up

// Interest = Principal * rate * time in years public double InterestAmount(double P, double r, double t) { return P * (r / 100) * t; } } }

2. Access the Program.cs file C# 3.0 Practical Learning
388

3. To declare and use a delegate, change the Program.cs file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace WattsALoan1 { delegate double Add2Values(double Value1, double Value2); public class Program { static int Main() { double Principal, IntRate, Period, AmountPaidAsInterest; int TypeOfPeriod = 0; double Periods = 0D; string PeriodName = null; LoanEvaluation loan = new LoanEvaluation(); Console.WriteLine("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"); 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("Loan Processing\n"); Principal = loan.GetPrincipal(); IntRate = loan.GetInterestRate(); Period = loan.GetPeriod(ref TypeOfPeriod, ref Periods); AmountPaidAsInterest = loan.InterestAmount(Principal, IntRate, Period); // A lambda expression Add2Values Add = (double Value1, double Value2) => { return Value1 + Value2; }; if (TypeOfPeriod == 0) { // Since the user made a bad selection, stop the program here "if" of would an return 0; }// Since this "if" condition has a "return 0" line, if the // condition produces true, the "return 0" means the function // would be terminated. If the condition is false, the inside // this "if" condition would not execute and the function // continue. This means that, if the condition is false, then // the "else' is implied. Therefore, we don't have to write // "else" condition: it is automatic. if (TypeOfPeriod == 1) {

C# 3.0 Practical Learning

389

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}", Add); Console.WriteLine("Interest paid on Loan: {0:C}", AmountPaidAsInterest); Console.WriteLine("==================================\n"); } } } return 0;

4. Execute the program and test it. 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: $12500 Enter the Interest Rate (%): 10.55 How do you want to enter the length of time? 1 - In Days 2 - In Months 3 - In Years Your Choice: 2 Enter the number of months: 42 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ================================== Estimate on loan ---------------------------------Principal: $12,500.00 Interest: 10.55 % Period: 42 months -------------------------------Total Amount Paid: $17,115.63 Interest paid on Loan: $4,615.63 ==================================

C# 3.0 Practical Learning

390

Press any key to continue . . .

5. Close the DOS window and return to your programming environment

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:
public delegate double Squared(double x); public class Circle { private double _radius; 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 arguments, the argument(s) must be provided in the parentheses of the called delegate. Here is an example:
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. You can define the associated method in a class other than the one where the delegate would be used. Here is an example:
using System; public class Exercise { public static double ValueTimesValue(double Value)

C# 3.0 Practical Learning

391

{ } return Value * Value;

}

static int Main() { return 0; }

You can also define the method 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 assign it to the variable. Here is an example:
using System; 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; } } public class Exercise { public static double ValueTimesValue(double Value) { return Value * Value; } static int Main() { Squared Sq = ValueTimesValue; return 0; } }

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; public delegate double Squared(double x); public class Circle { private double _radius;

C# 3.0 Practical Learning

392

public double Radius { get { return _radius; } set { _radius = value; } } public double Area(Squared sqd) { return sqd(_radius) * Math.PI; } } public class Exercise { public static double ValueTimesValue(double Value) { return Value * Value; } static int Main() { Squared Sqr = ValueTimesValue; Console.WriteLine("Circle Area: {0}\n", Sqr(24.68)); return 0; } }

This would produce:
Circle Area: 609.1024 Press any key to continue . . .

In the same way, you can use a lambda expression to implement an anonymous method that would be associated with a delegate. Here is an example:
using System; 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; }

}

C# 3.0 Practical Learning

393

public class Exercise { static int Main() { Squared Sqr = (a) => { return a * a; }; Console.WriteLine("Circle Area: {0}\n", Sqr(24.68)); } } return 0;

Delegates and Classes
Introduction
So far, we have learned how to create and use delegate of primitive types. We learned how to create a void delegate, how to create a delegate that returns a value, and how to create a delegate that takes one or more argument. Just as a reminder, here is an example:
using System; 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; } internal double Area() { return 6 * Side * Side; } internal double Volume() { return Side * Side * Side;

C# 3.0 Practical Learning

394

} } public class Exercise { static int Main() { Cube SmallBox = new Cube(25.58); Multiplication AreaDefinition = SmallBox.Area; Multiplication VolDefinition = SmallBox.Volume; Console.WriteLine("Cube Characteristics"); Console.WriteLine("Side: {0}", SmallBox.Side); Console.WriteLine("Area: {0}", AreaDefinition); Console.WriteLine("Volume: {0}\n", VolDefinition); } } return 0;

This would produce:
Cube Characteristics Side: 25.58 Area: 3926.0184 Volume: 16737.925112

A Delegate that Returns an Object
A delegate can be created to return a value that is of a class type. Of course you must know the class you want to use because the compiler would like to know the type of value that the delegate would return. You can use one of the many built-in classes of the .NET Framework or you can create your own class. When creating the delegate, specify the name of the class to its left as the returned type of value. Here is an example:
delegate Person Creator(); public class Person { public string FirstName; public string LastName; }

After doing this, you can create a method that implements the delegate. The method must return the same type of value as the delegate. Here is an example:
using System; delegate Person Creator(); public class Person { public string FirstName; public string LastName; }

C# 3.0 Practical Learning

395

public class Exercise { private static Person Create() { Person pers = new Person(); pers.FirstName = "Julius"; pers.LastName = "Krands"; return pers; } }

To use the delegate, declare a variable for it and assign the method to it. Here is an example:
using System; delegate Person Creator(); public class Person { public string FirstName; public string LastName; } public class Exercise { private static Person Create() { Person pers = new Person(); pers.FirstName = "Julius"; pers.LastName = "Krands"; return pers; } static int Main() { Creator crt = Create; } } return 0;

You can then call use the variable as you see fit. Instead of explicitly creating a method that implements the delegate, you can create an anonymous method using a lambda expression. In the body of the anonymous method, make sure you return a value of the type of the delegate. Here is an example:
using System; delegate Person Creator(); public class Person { public string FirstName; public string LastName; } public class Exercise {

C# 3.0 Practical Learning

396

static int Main() { Creator Create = () => { var PersonalInformation = new Person(); PersonalInformation.FirstName = "Julius"; PersonalInformation.LastName = "Krands"; }; return PersonalInformation;

} }

Create(); return 0;

A Delegate that Takes an Object as Argument
A delegate can be created to receive a class type as argument. When creating the delegate, in its parentheses, specify the class whose value it takes as argument. Here is an example:
using System; delegate void Anchor(Person p); public class Person { public string FirstName; public string LastName; }

To use the delegate, you can first create a method that implements the delegate, then declare a variable for the delegate and assign the method to it. If you prefer to create an anonymous method using a lambda expression, in the parentheses, enter a name for the argument and use that argument in the body of the method as you see fit. Here is an example:
public class Exercise { static int Main() { Anchor personal = (individual) => { Console.WriteLine("=//= Personal Information =//="); Console.WriteLine("First Name: {0}", sample.FirstName); Console.WriteLine("Last Name: {0}", sample.LastName); }; return 0; } }

You can then call the method as you see fit. Here is an example:
using System; delegate Person Creator();

C# 3.0 Practical Learning

397

delegate void Anchor(Person p); public class Person { public string FirstName; public string LastName; } public class Exercise { static int Main() { var PersonalInformation = new Person(); Creator Create = () => { PersonalInformation.FirstName = "Julius"; PersonalInformation.LastName = "Krands"; }; return PersonalInformation;

Anchor personal = (individual) => { Console.WriteLine("=//= Personal Information =//="); Console.WriteLine("First Name: {0}", individual.FirstName); Console.WriteLine("Last Name: {0}", individual.LastName); }; Create(); personal(PersonalInformation); return 0; } }

This would produce:
=//= Personal Information =//= First Name: Julius Last Name: Krands Press any key to continue . . .

In the same way:
• •

You can create a delegate that takes a class as argument and returns a class type You can create a delegate that takes more than one argument. One of the arguments could be a class type and the other(s) a class or a primitive type

Events
Introduction
C# 3.0 Practical Learning
398

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. 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.

C# 3.0 Practical Learning

399

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!"); } }

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: C# 3.0 Practical Learning
400

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;

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!"); } }

C# 3.0 Practical Learning

401

Structures
Fundamentals of Structures
Introduction
A structure is an enhanced version of the primitive data types we have used in previous lessons. Like a class, a structure is created from one variable of a primitive type or by combining various variables of primitive types. To create a structure, you use the same formula as for a class but with the struct keyword. Here is an example of a structure:
struct Integer { }

Like a class, a structure can have fields. They are listed in the body of the structure. Here is an example:
struct Integer { private int val; }

A structure can also have properties. Here is an example:
struct Integer { private int val; public int Value { get { return val; } set { val = value; } }

}

A structure can also have methods. Here is an example:
struct Integer { private int val; public int Value { get { return val; } set { val = value; } }

C# 3.0 Practical Learning

402

public int Read() { return int.Parse(Console.ReadLine()); } }

Structure Declaration
Like any other data type, to use a structure, you can first declare a variable from it. To allocation memory for a variable declared from a structure, use the new operator as done for a class. Here is an example:
using System; struct Integer { private int val; public int Value { get { return val; } set { val = value; } } public int Read() { return int.Parse(Console.ReadLine()); } } class Program { static int Main() { Integer Natural = new Integer(); return 0; } }

As done for variables of the other types and as seen for classes, to declare a variable for a structure, you can use the var keyword. After declaring the variable, you can use the object the same way you would a class. You can access its members (fields, properties, and methods) using the period operator. Here is an example:
using System; struct Integer { private int val; public int Value { get { return val; } set { val = value; } }

C# 3.0 Practical Learning

403

public int Read() { return int.Parse(Console.ReadLine()); } } class Program { static int Main() { var Natural = new Integer(); Console.Write("Enter a natural number: "); // Accessing a property of the structure Natural.Value = // Calling a method of the structure Natural.Read(); Console.WriteLine("The value you entered was: {0}", Natural.Value); return 0; } }

Here is an example of running the program:
Enter a natural number: 248 The value you entered was: 248 Press any key to continue . . .

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. Like primitive data types and unlike a class, a structure is a value type.

Techniques of Using Structures
A Structure as a Property
Once a structure exists, you can use it like a data type. For example, you can create a property that is a structure type. The rules are the same we reviewed for creating a property of a class. After creating the property, you can use it as you see fit. Here is an example:
using System; public struct Real { private double val; public double Value { get { return val; } set { val = value; } }

C# 3.0 Practical Learning

404

public double Read() { return double.Parse(Console.ReadLine()); } } public struct Rectangle { Real len; Real hgt; public Real Length { get { return len; } set { len = value; } } public Real Height { get { return hgt; } set { hgt = value; } } public void CreateRectangle() { Real rat = new Real(); Console.WriteLine("Enter the dimensions of the rectangle"); Console.Write("Enter the length: "); len.Value = rat.Read(); Console.Write("Enter the height: "); hgt.Value = rat.Read(); } }

public class Program { static int Main() { var Rect = new Rectangle(); Rect.CreateRectangle(); Console.WriteLine(); Console.WriteLine("Rectangle Characteristics"); Console.WriteLine("Length: {0}", Rect.Length.Value); Console.WriteLine("Height: {0}", Rect.Height.Value); Console.WriteLine("Perimeter: {0}", (Rect.Length.Value + Rect.Height.Value) * 2); Console.WriteLine("Area: {0}", Rect.Length.Value * Rect.Height.Value); } } return 0;

Here is an example of running the program:
Enter the dimensions of the rectangle

C# 3.0 Practical Learning

405

Enter the length: 44.84 Enter the height: 26.75 Rectangle Characteristics Length: 44.84 Height: 26.75 Perimeter: 143.18 Area: 1199.47 Press any key to continue . . .

Returning a Structure From a Method
Like regular data type or a class, a structure can serve as the return type of a method. The rules are more related to those of a class. When creating the method, type the name of the structure on the left side of the name of the method. In the body of the method, implement the desired behavior. Before exiting the method, make sure you return a valid value that is of the type of the structure. When a method returns a value of the type of a structure, you can assign the method to a variable of the type of the structure. Here is an example of implementing a method that returns a structure type, including calling the method and using its value:
using System; public struct Real { private double val; public double Value { get { return val; } set { val = value; } } public double Read() { return double.Parse(Console.ReadLine()); } } public struct Rectangle { Real len; Real hgt; public Real Length { get { return len; } set { len = value; } } public Real Height { get { return hgt; } set { hgt = value; } }

C# 3.0 Practical Learning

406

public void CreateRectangle() { Real rat = new Real(); Console.WriteLine("Enter the dimensions of the rectangle"); len = GetLength(); Console.Write("Enter the height: "); hgt.Value = rat.Read();

}

public Real GetLength() { Real rat = new Real(); Console.Write("Enter the length: "); rat.Value = rat.Read(); return rat; } }

public class Program { static int Main() { var Rect = new Rectangle(); Rect.CreateRectangle(); Console.WriteLine(); Console.WriteLine("Rectangle Characteristics"); Console.WriteLine("Length: {0}", Rect.Length.Value); Console.WriteLine("Height: {0}", Rect.Height.Value); Console.WriteLine("Perimeter: {0}", (Rect.Length.Value + Rect.Height.Value) * 2); Console.WriteLine("Area: {0}", Rect.Length.Value * Rect.Height.Value); } } return 0;

Here is an example of running the application:
Enter the dimensions of the rectangle Enter the length: 36.04 Enter the height: 22.86 Rectangle Characteristics Length: 36.04 Height: 22.86 Perimeter: 117.8 Area: 823.8744 Press any key to continue . . .

Passing a Structure as Argument
Like a data type, a structure can be passed as argument to a method. The argument is primarily passed as done for a class. After passing the argument, C# 3.0 Practical Learning
407

in the body of the method, you can access the public members of the structure, using the period operator. Here is an example:
using System; public struct Real { private double val; public double Value { get { return val; } set { val = value; } } public double Read() { return double.Parse(Console.ReadLine()); }

}

public struct Rectangle { Real len; Real hgt; public Real Length { get { return len; } set { len = value; } } public Real Height { get { return hgt; } set { hgt = value; } } public void CreateRectangle() { Real rat = new Real(); Console.WriteLine("Enter the dimensions of the rectangle"); len = GetLength(); Console.Write("Enter the height: "); hgt.Value = rat.Read(); } public Real GetLength() { Real rat = new Real(); Console.Write("Enter the length: "); rat.Value = rat.Read(); return rat;

} }

public class Program {

C# 3.0 Practical Learning

408

public static void ShowCharacteristics(Rectangle rect) { Console.WriteLine("Rectangle Characteristics"); Console.WriteLine("Length: {0}", rect.Length.Value); Console.WriteLine("Height: {0}", rect.Height.Value); Console.WriteLine("Perimeter: {0}", (rect.Length.Value + rect.Height.Value) * 2); Console.WriteLine("Area: {0}", rect.Length.Value * rect.Height.Value); } static int Main() { var Rect = new Rectangle(); Rect.CreateRectangle(); Console.WriteLine(); ShowCharacteristics(Rect); return 0; } }

Here is an example of running the program:
Enter the dimensions of the rectangle Enter the length: 114.55 Enter the height: 82.72 Rectangle Characteristics Length: 114.55 Height: 82.72 Perimeter: 394.54 Area: 9475.576 Press any key to continue . . .

When you pass a structure to a method as we did above, it referred to as passing by value. A copy of the value of the structure is passed to the method. If the method modifies the argument, the original variable would stay intact. If you want the method to modify the value of the structure, you can pass the argument by reference. You can do this using the (rules of the) ref and the out keywords. Here is an example of passing a structure by reference using the ref keyword:
using System; public struct Real { private double val; public double Value { get { return val; } set { val = value; } } public double Read() { return double.Parse(Console.ReadLine());

C# 3.0 Practical Learning

409

} } public struct Rectangle { Real len; Real hgt; public Real Length { get { return len; } set { len = value; } } public Real Height { get { return hgt; } set { hgt = value; } } public void CreateRectangle() { Console.WriteLine("Enter the dimensions of the rectangle"); len = GetLength(); GetHeight(ref hgt); } public Real GetLength() { Real rat = new Real(); Console.Write("Enter the length: "); rat.Value = rat.Read(); return rat;

}

public void GetHeight(ref Real rl) { Real rat = new Real(); Console.Write("Enter the height: "); rl.Value = rat.Read();

} }

public class Program { static int Main() { Rectangle rect = new Rectangle(); rect.CreateRectangle(); Console.WriteLine(); Console.WriteLine("Rectangle Characteristics"); Console.WriteLine("Length: {0}", rect.Length.Value); Console.WriteLine("Height: {0}", rect.Height.Value); Console.WriteLine("Perimeter: {0}", (rect.Length.Value + rect.Height.Value) * 2); Console.WriteLine("Area: {0}",

C# 3.0 Practical Learning

410

rect.Length.Value * rect.Height.Value); return 0; } }

Here is an example of running the program:
Enter the dimensions of the rectangle Enter the length: 75.82 Enter the height: 55.64 Rectangle Characteristics Length: 75.82 Height: 55.64 Perimeter: 262.92 Area: 4218.6248 Press any key to continue . . .

Built-In Structures: The Integral Data Types
Introduction
The C# language (actually the .NET Framework) treats each primitive data type as a class. In fact, each data type was created as a structure. Some characteristics are common to many of these structures while some other aspects are unique to some others. To support the routine operations of regular variables, each structure that represents a primitive type is equipped with some member variables and methods.

Conversion to a String
With a value of a primitive type, at one time or another, you may need to convert the value of a variable from its type to a string. To support this, each structure of a primitive type is equipped with a method named ToString. This method is overloaded with various versions. One of the versions of this method takes no argument. The syntax of this method is:
public override string ToString();

Another version of this method takes as argument a string. This string holds an expression used to format the value of the variable that called the method. The syntax of this method is:
public string ToString(string format);

You can pass the desired string to format the value to be displayed.

Parsing a String
In Lesson 5, we saw how to retrieve a value from the console and convert it to the desired value. To support this operation, each structure of a primitive C# 3.0 Practical Learning
411

data type is equipped with a static method named Parse. The syntaxes of this method are:
byte public static byte Parse(string s); sbyte public static sbyte Parse(string s); short public static short Parse(string s); ushort <=> UInt16 public static ushort Parse(string s); int <=> Int32 public static int Parse(string s); uint <=> UInt32 public static uint Parse(string s); long <=> Int64 public static long Parse(string s);

unsigned long <=> uint64
public static ulong Parse(string s);

Here is an example of calling this method:
using System; class Program { static int Main() { double value = 0; Console.Write("Enter a Value: "); value = double.Parse(Console.ReadLine()); Console.WriteLine("Value Entered: {0}", value); return 0; } }

Here is an example of executing the program:
Enter a Value: 245.85 Value Entered: 245.85 Press any key to continue . . .

C# 3.0 Practical Learning

412

You can also parse a value that is not primarily known. To support values other than byte types, you can use another version of the Equals() method that takes as argument an object type. The syntaxes of this version of the method are:
byte public static byte Parse(string s) sbyte public static sbyte Parse(string s) short public static short Parse(string s) ushort <=> UInt16 public static ushort Parse(string s) int <=> Int32 public static int Parse(string s) uint <=> UInt32 public static uint Parse(string s) long <=> Int64 public static long Parse(string s)

unsigned long <=> uint64
public static ulong Parse(string s)

When calling this method, if a bad value is passed to the Parse() method, for example if the user enters an invalid value to a double.Parse(Console.ReadLine()) call, the program produces an error (in Lesson 17, we will learn that the program throws an exception). To assist you with this type of problem, each structure of a primitive type is equipped with a method named TryParse. This method is overloaded with two versions that each returns a bool. One of the versions of this method takes two arguments: a string and a variable passed as an out reference. The syntaxes of this method are:
byte public static bool TryParse(string s, out byte result) sbyte public static bool TryParse(string s, out sbyte result) short

C# 3.0 Practical Learning

413

public static bool TryParse(string s, out short result) ushort <=> UInt16 public static bool TryParse(string s, out ushort result) int <=> Int32 public static bool TryParse(string s, out int result) uint <=> UInt32 public static bool TryParse(string s, out uint result) long <=> Int64 public static bool TryParse(string s, out long result)

unsigned long <=> uint64
public static bool TryParse(string s, out ulong result)

Based on this, if a double variable calls this method, the first argument is passed a string and the second argument is passed as an out double. This means that the second argument is returned from the method also. When the TryParse() method is called:

If the first argument passed to the method is valid, the method returns two values: true and the entered value is stored in the out argument If the value of the first argument is invalid, the method returns false and the default value of the data type is stored in the out argument. For example, if the variable that called the method is on type int but the user entered the wrong value, the method returns two values: false and 0 (because 0 is the default value of an int. If the variable that called the method is on type char but the user entered a bad value, the method returns two values: false and an empty character (because the default value of a char is empty).

Here is another example of running the above program:
Enter a Value: 506GH False: Value Entered = 0 Press any key to continue . . .

Notice that the compiler didn't produce (throw) an error (an exception).

The Minimum and Maximum Values of a Primitive Type
In Lesson 1, we saw that, when you declare a variable, the compiler reserves an amount of memory space preparing to store its value. As different variables have different requirements, some of them use less or more memory than others. When you declare a variable, the data type you specify allows the compiler to know how mush space would be needed to store the value of that variable. There is a minimum and a maximum values that can be stored in the memory space reserved for a variable. Based on this, a value 414 C# 3.0 Practical Learning

such as 224855 can be stored in space reserved for an int variable but it is beyond the space reserved for a Byte or a short. To help you find out the minimum value that a data type can hold, each structure of a primitive type is equipped with a constant member named MinValue. In the same way, the maximum value that a data type can support is represented by a constant field named MaxValue. You can check these minimum and maximum with the following program:
using System; class Program { static int Main() { Console.WriteLine( "================================================================= ======"); Console.WriteLine("C# Type .NET Structure Minimum Maximum"); Console.WriteLine( "================================================================= ======"); Console.WriteLine("char Char {0}\t\t\t{1}", char.MinValue, char.MaxValue); Console.WriteLine( "----------------------------------------------------------------------"); Console.WriteLine("byte Byte {0}\t\t\t{1}", byte.MinValue, byte.MaxValue); Console.WriteLine( "----------------------------------------------------------------------"); Console.WriteLine("sbyte SByte {0}\t\t\t{1}", sbyte.MinValue, sbyte.MaxValue); Console.WriteLine( "----------------------------------------------------------------------"); Console.WriteLine("short Int16 {0}\t\t\t{1}", short.MinValue, short.MaxValue); Console.WriteLine( "----------------------------------------------------------------------"); Console.WriteLine("ushort UInt16 {0}\t\t\t{1}", UInt16.MinValue, UInt16.MaxValue); Console.WriteLine( "----------------------------------------------------------------------"); Console.WriteLine("int Int32 {0}\t\t{1}", int.MinValue, int.MaxValue); Console.WriteLine( "----------------------------------------------------------------------"); Console.WriteLine("uint UInt32 {0}\t\t\t{1}", UInt32.MinValue, UInt32.MaxValue); Console.WriteLine( "----------------------------------------------------------------------"); Console.WriteLine("long Int64 {0}\t{1}",

C# 3.0 Practical Learning

415

long.MinValue, long.MaxValue); Console.WriteLine( "----------------------------------------------------------------------"); Console.WriteLine("uint64 UInt64 {0}\t\t\t{1}", UInt64.MinValue, UInt64.MaxValue); Console.WriteLine( "----------------------------------------------------------------------"); Console.WriteLine("float Single {0}\t\t{1}", float.MinValue, float.MaxValue); Console.WriteLine( "----------------------------------------------------------------------"); Console.WriteLine("double Double {0}\t{1}",| double.MinValue, double.MaxValue); Console.WriteLine( "----------------------------------------------------------------------"); Console.WriteLine("decimal Decimal {0} {1}", decimal.MinValue, decimal.MaxValue); Console.WriteLine( "============================================================="); return 0; } }

This would produce:
======================================================================= C# Type .NET Structure Minimum Maximum ======================================================================= char Char ? ----------------------------------------------------------------------byte Byte 0 255 ----------------------------------------------------------------------sbyte SByte -128 127 ----------------------------------------------------------------------short Int16 -32768 32767 ----------------------------------------------------------------------ushort UInt16 0 65535 ----------------------------------------------------------------------int Int32 -2147483648 2147483647 ----------------------------------------------------------------------uint UInt32 0 4294967295 ----------------------------------------------------------------------long Int64 -9223372036854775808 9223372036854775807 ----------------------------------------------------------------------uint64 UInt64 0 18446744073709551615 ----------------------------------------------------------------------float Single -3.402823E+38 3.402823E+38 ----------------------------------------------------------------------double Double -1.79769313486232E+308 1.79769313486232E+308 ----------------------------------------------------------------------decimal Decimal -79228162514264337593543950335 79228162514264337593543950335 ============================================================= Press any key to continue . . .

C# 3.0 Practical Learning

416

Value Comparisons
One of the most common operations performed on variables consists of comparing their values: to find out whether they are equal or to know whether one is higher than the other. These operations can be performed using the Boolean operators we reviewed in Lesson 8. The Boolean operations are part of the C# language. To formally implement them, each structure of a data type is equipped with a method named CompareTo that is overloaded with two versions. One of the implementations of the CompareTo() method compares a value or the value of a variable of the same type, with the variable that calls the method. This method takes one argument that is the same type as the variable that is calling it. The syntaxes of this method are:
byte public int CompareTo(byte value) sbyte public int CompareTo(sbyte value) short public int CompareTo(short value) ushort <=> UInt16 public int CompareTo(ushort value) int <=> Int32 public int CompareTo(int value) uint <=> UInt32 public int CompareTo(uint value) long <=> Int64 public int CompareTo(long value)

unsigned long <=> uint64
public int CompareTo(ulong value)

The method returns an int value. For example, imagine you have two int variables named Variable1 and Variable2, you can call the CompareTo() method of the first variable to compare its value to that of the second variable. This would be done as in:
int result = Variable1.CompareTo(Variable2);

The end result would be as follows:

C# 3.0 Practical Learning

417

• • •

If the value of Variable1 is greater than the value of Variable2, the method returns 1 If the value of Variable1 is less than the value of Variable2, the method returns -1 If the values of both variables are equal, the method returns 0

Here is an example:
using System; class Program { static int Main() { int Variable1 = 248; int Variable2 = 72937; int result = Variable1.CompareTo(Variable2); Console.WriteLine("{0} compared to {1} produces {2}", Variable1, Variable2, result); return 0; } }

This would produce:
248 compared to 72937 produces -1 Press any key to continue . . .

Another version of the CompareTo() method allows you to compare the value of a variable with a variable whose type is not the same as the variable that called it. Since all types and classes of C# are based on object, this second version takes as argument an object object. The method return an int value. The syntax of this version is:
public int CompareTo(object value);

Notice that you can use the CompareTo() method to test for equality. Another method used to check the equality of two variables is the Equals() method. The Equals() method is overloaded in two versions and each takes one argument. The Equals() method returns a Boolean value. One of the versions of this method takes as argument a value of the same type as the variable that called it. The syntaxes of this version are:
byte public bool Equals(byte obj) sbyte public bool Equals(sbyte obj) short public bool Equals(short obj) ushort <=> UInt16

C# 3.0 Practical Learning

418

public bool Equals(ushort obj) int <=> Int32 public bool Equals(int obj) uint <=> UInt32 public bool Equals(uint obj) long <=> Int64 public bool Equals(long obj)

unsigned long <=> uint64
public bool Equals(ulong obj)

The method compares the values of the variable that called it and the argument, as in
bool result = Variable1.Equals(Variable2);

The comparison is performed as follows:
• •

If the value of the first variable is the same as that of the second variable, the method returns true If the values of the variables are different, the method returns false

Here is an example:
using System; class Program { static int Main() { int Variable1 = 1407; int Variable2= 59266; bool result = value1.Equals(value2); Console.WriteLine("{0} = {1} produces {2}", Variable1, Variable2, result); return 0; } }

This would produce:
1407 = 59266 produces False Press any key to continue . . .

The other version of the Equals() method takes as argument an object value. The syntax of this version is:
public override bool Equals(object obj);

C# 3.0 Practical Learning

419

Here is an example:
using System; class Program { static int Main() { int value1 = 824; object value2 = 824; bool result = value1.Equals(value2); Console.WriteLine("{0} = {1} produces {2}", value1, value2, result); return 0; } }

This would produce:
824 = 824 produces True Press any key to continue . . .

Built-In Structures: The Boolean Type
Introduction
As seen in previous lessons, the bool data type is used to represent a value considered as being true or false. In the .NET Framework, the bool data type is represented by the Boolean structure. The true value of a bool variable is represented by the TrueString field and the false value is represented by the FalseString member variable. In other words, when true (or false) is represented as a string, "true" (or "false"” is the same as TrueString (or FalseString).

Parsing a Boolean Variable
We saw in a Lesson 8 that you could retrieve the value of a Boolean variable from a user. To support this, the Boolean structure is equipped with a static method named Parse. The Boolean.Parse() method is declared as follows:
public static bool Parse(string value);

This method takes as argument a string. The argument must contain either the word True (case-insensitive) or the word False. If the argument is passed as "True", the method returns true. If the argument is "false", this method returns false. Here is an example:
using System; class Program { static int Main() { bool result = bool.Parse("TRUE");

C# 3.0 Practical Learning

420

Console.WriteLine("Result: {0}", result); return 0; } }

This would produce:
Result: True Press any key to continue . . .

When calling the Boolean.Parse() method to retrieve the value of a Boolean variable, if the supplied value is "TRUE" or "FALSE", the compiler would process it. If the value is not valid, the program would produce an error. Here is an example:
using System; class Program { static int Main() { bool HouseHas3Bedrooms = bool.Parse("ItHas3Bedrooms"); Console.WriteLine("House has 3 bedrooms: {0}", HouseHas3Bedrooms); return 0; } }

To avoid the error, the Boolean structure provides the TryParse() method. Its syntax is:
public static bool TryParse(string value, out bool result);

The first argument is the value to be parsed. If that value is valid, the second argument holds the True or False value of the first. Here is an example:
using System; class Program { static int Main() { bool alt; bool HouseHas3Bedrooms = bool.TryParse("True", out alt); Console.WriteLine("House has 3 bedrooms: {0}", HouseHas3Bedrooms); Console.WriteLine("Alternate value: {0}", alt); return 0; } }

This would produce:
House has 3 bedrooms: True Alternate value: True Press any key to continue . . .

C# 3.0 Practical Learning

421

Consider this other version of the same program:
using System; class Program { static int Main() { bool alt; bool HouseHas3Bedrooms = bool.TryParse("False", out alt); Console.WriteLine("House has 3 bedrooms: {0}", HouseHas3Bedrooms); Console.WriteLine("Alternate value: {0}", alt); return 0; } }

This would produce:
House has 3 bedrooms: True Alternate value: False Press any key to continue . . .

Notice that the first argument returns True although it was passed as False. This means that, if the value of the first argument is valid, it is the second argument, not the first, that holds the result. If the first argument is not valid, the second argument returns a False value. Consider the following version of the program:
using System; class Program { static int Main() { bool alt; bool HouseHas3Bedrooms = bool.TryParse("Don't Know", out alt); Console.WriteLine("House has 3 bedrooms: {0}", HouseHas3Bedrooms); Console.WriteLine("Alternate value: {0}", alt); return 0; } }

This would produce:
House has 3 bedrooms: False Alternate value: False Press any key to continue . . .

Comparisons of Boolean Variables
In C#, to compare the values of two Boolean variables for equality, you can use the equality operator "==". Here is an example:
using System;

C# 3.0 Practical Learning

422

class Program { static int Main() { bool House1Has3Bedrooms = true; bool House2Has3Bedrooms = false; Console.WriteLine("House1 House1Has3Bedrooms); Console.WriteLine("House2 House2Has3Bedrooms); Console.WriteLine("House1 {0}", House1Has3Bedrooms == return 0; } } has 3 bedrooms: {0}", has 3 bedrooms: {0}", and House2 have the number of bedrooms: House2Has3Bedrooms);

This would produce:
House1 has 3 bedrooms: True House2 has 3 bedrooms: False House1 and House2 have the number of bedrooms: False Press any key to continue . . .

To support this comparison, the Boolean structure of the .NET Framework is equipped with the Equals() method. Its syntax is:
public bool Equals(bool obj);

This method takes one argument as the Boolean value or variable to be compared to the variable that called it. Here is an example of calling it:
using System; class Program { static int Main() { bool House1Has3Bedrooms = false; bool House2Has3Bedrooms = false; Console.WriteLine("House1 has 3 bedrooms: {0}", House1Has3Bedrooms); Console.WriteLine("House2 has 3 bedrooms: {0}", House2Has3Bedrooms); Console.WriteLine("House1 and House2 have the number of bedrooms: {0}", House1Has3Bedrooms.Equals(House2Has3Bedrooms)); return 0; } }

This would produce:
House1 has 3 bedrooms: False House2 has 3 bedrooms: False House1 and House2 have the number of bedrooms: True Press any key to continue . . .

C# 3.0 Practical Learning

423

The Equals() method can easily be called by one Boolean variable that receives another Boolean variable as argument. If you don't know the exact type of value of the argument, you can still pass it an object value. To support this, the Equals() method has another version whose syntax is:
public override bool Equals(Object obj);

This version takes as argument a variable that is of any type. Besides the equality, you can also compare two Boolean variables to know whether one is lower than the other. To support this, the Boolean structure is equipped with the CompareTo() method. Its syntax is:
public int CompareTo(bool value);

If the type of variable is not necessarily a Boolean type, you can pass it as an object value. To do this, you can use the other version of the CompareTo() method. Its syntax is:
public int CompareTo(Object obj);

Floating-Point Numbers
Introduction
As seen in Lesson 2, to support floating-point numbers, you can use the float, the double, or the decimal data types. The C# float data type originates from the Single structure of the .NET Framework. The double data type is based on the Double structure of the .NET Framework. The C# decimal data type is type-defined from the .NET Framework’s Decimal structure. To declare a floating-point variable, you can use one of these data types and initialize it. When initializing a floating-point variable, you should make sure you assign it a value that can fit in the memory allocated for it. As mentioned for the integer data types, the minimum value that a float variable can hold is represented by the MinValue constant of the Single structure and the MinValue field of the Double. The maximum value that a float or a double variable can hold is named MaxValue. After declaring and initializing a float or a double variable, it should hold an appropriate value. If you get the variable’s value some other way, at one time or another, you may not know what value is stored in the memory allocated for the variable. In fact, the variable may hold a value that is not a number. To check whether the variable is holding a value that is not a number, you can access its NaN constant. To do this, type the float or double data type, followed by the period operator, and followed by the NaN constant. Here is an example:
using System; class Program { static int Main()

C# 3.0 Practical Learning

424

{ double number = 0D; if( number == double.NaN ) Console.WriteLine("The value is not a number"); return 0;

} }

Another technique you can use to check this characteristic is to IsNaN() method of either the Single or the Double structure.

Operations on Floating-Point Numbers
Using one integer and one floating-point number, or with two floating-point numbers, you can perform one of the routine arithmetic operations such as the addition, the subtraction, the multiplication, or the division. When it comes to the division and if performed on two constants, you can get a positive or a negative number. In highly precise calculations, you may have to deal with an approximate number whose exact value is not known. For example, the smallest positive number is called epsilon. In the Double and the Single structures, this constant is named Epsilon. For the single-precision type, the epsilon is equal to 1.445. For a double-precision type, the epsilon constant is equivalent to 4.94065645841247-324. As you can see, this number is extremely low. When dealing with real numbers, some operations produce very little or very large numbers. In algebra, the smallest number is called negative infinity. In the .NET Framework, the negative infinity is represented by a constant named NegativeInfinity. To access this number, type either float or double, followed by a period operator, followed by the name of this constant. Here is an example:
using System; class Program { static int Main() { Console.WriteLine("Negative Infinity = {0}", double.NegativeInfinity); return 0; } }

To find out if a variable holds a negative infinity value, you can call the IsNegativeInfinity() method from the variable. The syntaxes of this method are:
public static bool IsNegativeInfinity(float f); public static bool IsNegativeInfinity(double d);

On the other extreme, the possible largest number is named positive infinity. This constant is represented in the .NET Framework by the PositiveInfinity value. To access this constant, type float or double, followed by the period, followed by the name of this constant. To find out if a variable’s value is a C# 3.0 Practical Learning
425

positive infinity, you can call its IsPositiveInfinity() method. The syntaxes of this method are:
public static bool IsPositiveInfinity(float f); public static bool IsPositiveInfinity(double d);

To check whether the value of a variable is one of the infinities, you can call its IsInfinity() method. The syntaxes of this method are:
public static bool IsInfinity(float f); public static bool IsInfinity(double d);

Comparison Operations
Because floating-point numbers can be approximate, you should be careful when comparing them, especially for equality. Consider the following examples:
using System; class Program { static int Main() { double number1 = 22.15D; double number2 = 22.15D; if( number1 == number2 ) Console.WriteLine("The values are equal"); return 0;

} }

This would produce:
The values are equal Press any key to continue . . .

For the sake of discussion, these values of these variables were limited to 2 decimal places. If they represented hourly salaries of employees, the comparison would be easily performed and can produce an exact result. If you want to apply more precision do the numbers, for example if the variables represent weight values, you would need more places on the right side of the decimal separator. Consider the following program:
using System; class Program { static int Main() { double number1 = 22.156D; double number2 = 22.157D; if( number1 == number2 ) Console.WriteLine("The values are equal"); else Console.WriteLine("The values are NOT equal");

C# 3.0 Practical Learning

426

return 0; } }

This would produce:
The values are NOT equal Press any key to continue . . .

This time, because of more precision, the variables don’t hold the same value. Besides the equality, you can also compare floating-point variables to find out if one has a value lower than the other. To support such operations, the Single and the Double structures are equipped with a method named CompareTo. The rules of this method are functionally the same as those we reviewed for integers.

C# 3.0 Practical Learning

427

Built-In 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 Microsoft Visual C# and create a Console Application named Sport1 2. To create a new class, in the Solution Explorer, right-click Sport1 -> Add -> Class... 3. Set the Name to Sport and click Add 4. Change the file as follows:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Sport1 { class Sport { private double _ballWeight; private int _players; private double _courtLength; private double _courtWidth;

C# 3.0 Practical Learning

428

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; } }

} }

5. Access the Program.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Sport1 { class Program { static int Main() { Sport tennis = new Sport(); tennis.BallWeight = 57.50; // grams tennis.NumberOfPlayers = 1; // Singles game tennis.CourtLength = 23.70; // meters tennis.CourtWidth = 8.23; // meters; Console.WriteLine("Sport 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; } } }

C# 3.0 Practical Learning

429

6. Execute the application:
Sport Characteristics Ball Weight: 57.5 grams Players on each side: 1 Court Dimensions(LxW): 23.7m X 8.23m Press any key to continue . . .

7. Close the DOS window

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:
The first and the second books have different number of pages The first and the third books have the same number of pages

C# 3.0 Practical Learning

430

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. Access the Sport.cs file 2. To create your own implementation of the Equals() method, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Sport1 { class Sport { . . . public double CourtWidth { get { return _courtWidth; } set { _courtWidth = value; } } 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; } } }

3. Access the Program.cs file and change it as follows: C# 3.0 Practical Learning
431

using using using using

System; System.Collections.Generic; System.Linq; System.Text;

namespace Sport1 { class Program { static int Main() { Sport Euro2002 = new Sport(); Sport CAN2004 = new Sport(); Sport tennis = new Sport(); Euro2002.BallWeight = 435; // grams Euro2002.NumberOfPlayers = 11; // persons for each team Euro2002.CourtLength = 100; // meters Euro2002.CourtWidth = 60; // meters tennis.BallWeight = 57.50; // grams tennis.NumberOfPlayers = 1; // Singles game tennis.CourtLength = 23.70; // meters tennis.CourtWidth = 8.23; // meters; CAN2004.BallWeight = 435; // grams CAN2004.NumberOfPlayers = 11; // persons for each team CAN2004.CourtLength = 100; // meters CAN2004.CourtWidth = 60; // 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; } } }

4. Execute the application. This would produce:
The Euro2002 and the tennis variables are not equal The Euro2002 and CAN2004 variables are equal Press any key to continue . . .

5. Close the DOS window

Stringing a Class
C# 3.0 Practical Learning
432

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()); return 0; } }

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. Access the Sport.cs file 2. To implement and use a ToString() method, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Sport1 { class Sport { private double _ballWeight; private int _players; private double _courtLength; private double _courtWidth; public double BallWeight { get { return _ballWeight; } set { _ballWeight = value; } }

C# 3.0 Practical Learning

433

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 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;

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;

3. Access the Program.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

C# 3.0 Practical Learning

434

namespace Sport1 { class Program { static int Main() { Sport CAN2004 = new Sport(); Sport tennis = new Sport(); tennis.BallWeight = 57.50; // grams tennis.NumberOfPlayers = 1; // Singles game tennis.CourtLength = 23.70; // meters tennis.CourtWidth = 8.23; // meters; CAN2004.BallWeight = 435; // grams CAN2004.NumberOfPlayers = 11; // persons for each team CAN2004.CourtLength = 100; // meters CAN2004.CourtWidth = 60; // meters Console.WriteLine("===================================="); Console.WriteLine("Cup Game Characteristics"); Console.Write("------------------------------------"); Console.WriteLine(CAN2004); Console.WriteLine("\n===================================="); Console.WriteLine("Tennis Game Characteristics"); Console.Write("------------------------------------"); Console.WriteLine(tennis); Console.WriteLine("\n===================================="); } } } return 0;

4. Execute 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 ==================================== Press any key to continue . . .

5. Close the DOS window

Boxing and Un-Boxing
C# 3.0 Practical Learning
435

When we study inheritance, we will learn that all data types used in a C# program are "based on" an object called object. As introduced earlier, you can use this data type to declare a variable that would hold any type of value. Because this is some type of a "universal" data type, it can also be initialized with any value. Here are examples:
using System; class Exercise { static void Main() { object Number = 244; object Thing = "Professor Kabba"; Console.WriteLine(Number); Console.WriteLine(Thing);

} }

This would produce:
244 Professor Kabba

As you can see, when an object variable is initialized, the compiler finds out the type of value that was assigned to it. This is referred to as boxing. This mechanism is transparently done in C# (and in Visual Basic but not in Visual C++ 2003 (it is possible that something will be done in the next version, or not)). If you declare a variable using a primitive data type (int, float, double, etc), at one time, you may be interested in converting the value of that variable into an object. Here is an example:
using System; class Exercise { static int Main() { int Number = 244; object Thing = Number; Console.WriteLine(Number); Console.WriteLine(Thing); return 0;

} }

This would produce:
244 244

This operation is referred to as unboxing. As you can see, this operation is performed transparently (Visual C++ 2003 doesn't do it transparently).

C# 3.0 Practical Learning

436

Boxing and unboxing make C# a very flexible and wonderful language (if you misuse it, of course it can be dangerous).

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.

Other Built-In Classes
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.

Random numbers
Introduction
Imagine you have a series of numbers, such these: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, and 20. Imagine you want to select one of these numbers, any of them. A number is referred to as random if it has been selected from a pool without a specific pattern to follow. For example, if you decide to select the value 17 from this list, if there was an exact reason that number was selected, then it is not considered random. In reality, it is difficult for a number to qualify as random. For this reason, most random numbers are referred to as pseudo-random.

Getting a Random Number
To support the ability to create or choose a random number, the .NET Framework provides the Random class. To start, you can declare a variable of this class, using one of its two constructors. Here is an example that uses the default constructor:
using System; class Program { static int Main() {

C# 3.0 Practical Learning

437

Random rndNumber = new Random(); return 0; } }

After creating the variable, you can start getting numbers from it. To do this, you call the Next() method, which is overloaded in three versions. One of the versions of this method takes no argument and its syntax is:
public virtual int Next();

This method generates a randomly selected integer between 0 and the MinValue value of the int data type. Here is an example:
using System; class Program { static int Main() { Random rndNumbers = new Random(); int rndNumber = rndNumbers.Next(); Console.WriteLine("Number: {0}", rndNumber); } } return 0;

Here is an example of running the program:
Number: 1369872590 Press any key to continue . . .

In the same way, you can call this version of the Next() method repeatedly to get random. Here is an example:
using System; class Program { static int Main() { Random rndNumbers = new Random(); int rndNumber = 0; for (int nbr = 1; nbr < 9; nbr++) { rndNumber = rndNumbers.Next(); Console.WriteLine("Number: {0}", rndNumber); } } } return 0;

Here is an example of running the program:
Number: 1924504148 Number: 1257846191

C# 3.0 Practical Learning

438

Number: 424740120 Number: 1009211682 Number: 544356245 Number: 708951978 Number: 759684741 Number: 1325535324 Press any key to continue . . .

The Seed of a Random Number
Consider the following program:
using System; class Program { static int Main() { Random rndNumbers = new Random(); int rndNumber = rndNumbers.Next(); Console.WriteLine("Number: {0}", rndNumber); return 0; } }

Here is an example of running the program:
Number: 573991745 Press any key to continue . . .

Here is another example of running the same program:
Number: 334223329 Press any key to continue . . .

Notice that the numbers generated are different. When creating a program that repeatedly gets a series of random numbers, you may (or may not) want the Random class to generate the same number over and over again. A seed is a constant value that controls whether a random generation would produce the same result every time it occurs. For example, using a seed, you can impose it upon the Random class to generate the same number every time the Next() method is called. To support the ability to use a seed, the Random class is equipped with a second constructor whose syntax is:
public Random(int Seed);

Based on this, to specify a seed, when declaring a Random variable, pass a constant integer to the constructor. Here is an example:
using System; class Program { static int Main() { Random rndNumbers = new Random(20); int rndNumber = rndNumbers.Next();

C# 3.0 Practical Learning

439

Console.WriteLine("Number: {0}", rndNumber); } } return 0;

Here is one example of running the program:
Number: 375271809 Press any key to continue . . .

Here is another example of running the same program:
Number: 375271809 Press any key to continue . . .

Notice that the numbers are the same. Consider this program also:
using System; class Program { static int Main() { Random rndNumbers = new Random(20); int rndNumber = 0; for (int nbr = 1; nbr < 5; nbr++) { rndNumber = rndNumbers.Next(); Console.WriteLine("Number: {0}", rndNumber); } return 0; } }

Here is one example of running the program:
Number: 375271809 Number: 1472524622 Number: 1605850688 Number: 1776011503 Press any key to continue . . .

Here is another example of running the same program:
Number: 375271809 Number: 1472524622 Number: 1605850688 Number: 1776011503 Press any key to continue . . .

Notice that the sequences are the same. In both cases, this indicates that, if you specify a seed, the Random class would generate the same number or the same sequence of numbers.

Generating Random Numbers in a Range of Numbers
C# 3.0 Practical Learning
440

So far, we have been using with any number that would fit an integer. In some assignments, you may want to restrict the range of numbers that can be extracted. Fortunately, the Random class allows this. Using the Random class, you can generate random positive numbers up to a maximum of your choice. To support this, the Random class is equipped with another version of the Next() method whose syntax is:
public virtual int Next(int maxValue);

The argument to pass to the method determines the highest integer that can be generated by the Next() method. The method returns an integer. Here is an example that generates radom numbers from 0 to 20:
using System; class Program { static int Main() { Random rndNumbers = new Random(); int rndNumber = 0; for (int nbr = 1; nbr < 9; nbr++) { rndNumber = rndNumbers.Next(20); Console.WriteLine("Number: {0}", rndNumber); } } } return 0;

Here is an example of running the program:
Number: 1 Number: 7 Number: 1 Number: 16 Number: 14 Number: 19 Number: 3 Number: 1 Press any key to continue . . .

The above version of the Next() method generates numbers starting at 0. If you want, you can specify the minimum and the maximum range of numbers that the Next() method must work with. To support this, the Random class is equipped with one more version of this method and that takes two arguments. Its syntax is:
public virtual int Next(int minValue, int maxValue);

The first argument specifies the lowest value that can come from the range. The second argument holds the highest value that the Next() method can generate. Therefore, the method would operate between both values. Here is an example that generates random numbers from 6 to 18:
using System;

C# 3.0 Practical Learning

441

class Program { static int Main() { Random rndNumbers = new Random(); int rndNumber = 0; for (int nbr = 1; nbr < 9; nbr++) { rndNumber = rndNumbers.Next(6, 18); Console.WriteLine("Number: {0}", rndNumber); } } } return 0;

Here is an example of running the program:
Number: 17 Number: 9 Number: 8 Number: 15 Number: 10 Number: 9 Number: 13 Number: 11 Press any key to continue . . .

Notice that the numbers are between 6 and 18.

Built-In Assemblies and Libraries
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 nonVisual 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 assembly 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

C# 3.0 Practical Learning

442

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 Microsoft.VisualBasic.dll library. Here is an example:
csc /reference:Microsoft.VisualBasic.dll Exercise.cs

reference

the

C# 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

C# 3.0 Practical Learning

443

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. To start a new project, on the main menu, click File -> New Project... 2. In the New Project dialog box, click Class Library 3. Set the Name to Operations1 and click OK 4. Change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Operations1 { 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; } public static double Division(double x, double y) { if (y == 0) return 0; return x / y; } } }

5. In the Solution Explorer, right-click Class1.cs and click Rename 6. Change the name to Operations.cs and press Enter 7. To save the project, on the Standard toolbar, click the Save All button 8. Click Save to save everything 9. On the main menu, click Project -> Operations1 Properties C# 3.0 Practical Learning
444

10. In the Output Type combo box, make sure Class Library is selected:

11.

Click the X button to close the Properties window

12. To create the library, on the main menu, click Build -> Build Solution 13. To start another project, on the main menu, click File -> New Project... 14. In the New Project dialog box, select Console Application

15. Set the Name to Algebra1 and press Enter 16. In the Solution Explorer, right-click References and click Add Reference... 17. Click the Browse tab

18. In the list of folders, double-click Operations1 and locate the Operations1.dll file (it should be in the Release (or the Debug) sub-folder of the bin folder)

C# 3.0 Practical Learning

445

19. Click Operations1.dll

20. Click OK. In the Solution Explorer, expand the References node if necessary and make sure that there is a new node labeled Operations1 21. Access the Program.cs file and change it as follows:

using System; namespace Algebra1 { class Program { static int Main() { double Number1 = 244.58; double Number2 = 5082.88; double Result = Operations1.Operations.Addition(Number1, Number2); Console.WriteLine("{0} + {1} = {2}\n", Number1, Number2, Result); return 0; } } }

22.

Execute the application to test it. This would produce:

244.58 + 5082.88 = 5327.46 Press any key to continue . . .

C# 3.0 Practical Learning

446

23.

Close the DOS window

A Library Created in Another Language
Using a Visual C++/CLI Library
One of the most important sought goals in .NET is to allow different languages to collaborate, such as sharing code. One way this can happen is to be able to use the functionality of one language into another. As an illustration, we saw earlier that you could use the rich library of Visual Basic functions in a C# application. As no library is ever complete, you may still need functionality that is not easily found. Furthermore, you may be working with a team of C++ programmers who have already created a set of functions or complex operations. You should be able to use that existing code.

Creating a Library
In previous years, it used to be a challenge to create a library, especially in C++. Fortunately, Microsoft Visual C++ now makes it particularly easy to create one, because a wizard highly assists you. To create a library, first display the New Project dialog box. After specifying Visual C++, in the Templates list, click Class Library and give it a name. In the body of the file, you can create the classes and/or functions as you see fit. Here is an example:
// Business.h #pragma once using namespace System; namespace Business { public ref class Finance { public: double CalculateDiscount(double MarkedPrice, double DiscountRate) { return MarkedPrice * DiscountRate / 100; } }; }

Once the project is ready, you must build it (on the main menu, Build -> Build Business). As a result, the compiler would create a file with the .dll extension:

C# 3.0 Practical Learning

447

Normally, as far as creating a library, that's it.

Using the Library
Creating a library in C++ is easy. To use it, there are a few rules you must follow. To start, you must make sure that your project can "physically" find the library. Probably the easiest way to take care of this is to copy the dll file and paste it in the folder that contains your project's executable. You can also do this directly in Visual Studio by importing the library file as we saw earlier. In your project, you should include the System.Runtime.InteropServices namespace. Before the section where the library will be accessed, enter the DllImport attribute that takes as argument the name of the library passed as a string. Here is an example:
using System; using System.Runtime.InteropServices; using Business; namespace DepartmentStore { class Exercise { [DllImport("Business.dll")] public static extern double CalculateDiscount(double price, double discount) static int Main() { Finance fin = new Finance(); double markedPrice = 275.50; double discountRate = 25.00; // % double discountAmount = fin.CalculateDiscount(markedPrice, discountDate); double netPrice = markedPrice - discountAmount); 448 C# 3.0 Practical Learning

Console.WriteLine("Marked Price: Console.WriteLine("Discount Rate: 100);

{0:C}", markedPrice); {0:P}", discountRate /

Console.WriteLine("Discount Amount: {0:C}", discountAmount); Console.WriteLine("Net Price: {0:C}\n", netPrice); } return 0;

}

}

This makes your library code ready to be used, which you can do as you would any other code. This means that you can compile your program the way we did in the previous section.

Using the Win32 Library
The Microsoft Windows operating system was originally written in C, the parent language of C++ and C# (also of Java and JavaScript). To allow programmers to create applications, Microsoft released a library called Win32. This is a series of functions and classes, etc, that you previously had to use. As time has changed, you don't need to exclusively use Win32 anymore to create a Windows application. Nonetheless, Win32 is still everywhere and it is not completely avoidable because many or some of the actions you would want to perform in a Windows application are still available only in Win32. Fortunately, in most cases, it is not always difficult to use some of these functions in a C# applications, as long as you observe some rules. Here is an example:
using System; using System.Runtime.InteropServices; namespace Win32Applied { class Program { [DllImport("Kernel32.dll")] public static extern bool SetConsoleTitle(string strMessage); static int Main() { SetConsoleTitle("C# Programming"); } } } return 0;

C# 3.0 Practical Learning

449

Introduction to Exception Handling
Introduction to Exceptions
Overview
During the execution of a program, the computer will face two types of situations: those it is prepared to deal with and those it is not. Imagine you write a program that requests a number from the user:
using System; class Program { static int Main() { double side; Console.WriteLine("Square Processing"); Console.Write("Enter Side: "); side = double.Parse(Console.ReadLine()); Console.WriteLine("\nSquare Characteristics"); Console.WriteLine("Side: {0}", side); Console.WriteLine("Perimeter: {0}", side * 4); return 0; } }

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 4 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 of error that could occur in your program, you can identify the error yourself and deal with it by telling the compiler what to do when this type of error occurs. C# 3.0 Practical Learning
450

Practical Learning: Introducing Exception Handling
1. Start Microsoft Visual C# and create a Console Application named
GeorgetownCleaningServices5

2. To create a new class, in the Solution Explorer, right-click GeorgetownCleaningServices2 -> Add -> Class... 3. Set the Name to CleaningOrderInfo and click OK 4. Change the file as follows:
using System; namespace GeorgetownCleaningServices5 { public class CleaningOrderInfo { // 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; } }

5. To create a new class, on the main menu, click Project -> Add Class... 6. Set the Name to OrderProcessing and press Enter 7. Change the file as follows:
using System; namespace GeorgetownCleaningServices5 { public class sealed OrderProcessing { #region Objects used to process an order // Price of items const decimal PriceOneShirt = 0.95M; const decimal PriceAPairOfPants = 2.95M; const decimal PriceOneDress = 4.55M; const decimal TaxRate = 0.0575M; // 5.75% CleaningOrderInfo cleaningOrder; // Each private private private of these sub totals will be used for cleaning items decimal SubTotalShirts; decimal SubTotalPants; decimal SubTotalDresses;

C# 3.0 Practical Learning

451

// Values used to process an order private decimal TotalOrder; private decimal TaxAmount; private decimal SalesTotal; private decimal AmountTended; private decimal Difference; #endregion #region Actions used to process and present an order public OrderProcessing() { cleaningOrder = new CleaningOrderInfo(); } public void ProcessOrder() { Console.WriteLine("-/- Georgetown Cleaning Services -/-"); // Request order information from the user Console.Write("Enter Customer Name: "); cleaningOrder.CustomerName = Console.ReadLine(); Console.Write("Enter Customer Phone: "); cleaningOrder.HomePhone = Console.ReadLine(); Console.Write("Enter the order date(mm/dd/yyyy): "); cleaningOrder.OrderDate = DateTime.Parse(Console.ReadLine()); Console.Write("Enter the order time(hh:mm AM/PM): "); cleaningOrder.OrderTime = DateTime.Parse(Console.ReadLine()); // Request the quantity of each category of items Console.Write("Number of Shirts: "); cleaningOrder.NumberOfShirts = uint.Parse(Console.ReadLine()); Console.Write("Number of Pants: "); cleaningOrder.NumberOfPants = uint.Parse(Console.ReadLine()); Console.Write("Number of Dresses: "); cleaningOrder.NumberOfDresses = uint.Parse(Console.ReadLine()); // Perform the necessary calculations SubTotalShirts = cleaningOrder.NumberOfShirts * PriceOneShirt; SubTotalPants = cleaningOrder.NumberOfPants * PriceAPairOfPants; SubTotalDresses = cleaningOrder.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

C# 3.0 Practical Learning

452

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}", cleaningOrder.CustomerName); Console.WriteLine("Home Phone: {0}", cleaningOrder.HomePhone); Console.WriteLine("Order Date: {0:D}", cleaningOrder.OrderDate); Console.WriteLine("Order Time: {0:t}", cleaningOrder.OrderTime); Console.WriteLine("------------------------------------"); Console.WriteLine("Item Type Qty Unit/Price Sub-Total"); Console.WriteLine("------------------------------------"); Console.WriteLine("Shirts {0,3} {1,4} {2,6}", cleaningOrder.NumberOfShirts, PriceOneShirt, SubTotalShirts); Console.WriteLine("Pants {0,3} {1,4} {2,6}", cleaningOrder.NumberOfPants, PriceAPairOfPants, SubTotalPants); Console.WriteLine("Dresses {0,3} {1,4} {2,6}", cleaningOrder.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("===================================="); } #endregion } }

8. Access the program.cs file and change it as follows: C# 3.0 Practical Learning
453

using System; namespace GeorgetownCleaningServices5 { class Program { static int Main() { OrderProcessing Order = new OrderProcessing(); Order.ProcessOrder(); return 0;

} } }

9. Execute the application and test it. Here is an example:
-/- Georgetown Cleaning Services -/Enter Customer Name: Peter Moonstruck Enter Customer Phone: (301) 728-8830 Enter the order date(mm/dd/yyyy): 04/22/2006 Enter the order time(hh:mm AM/PM): 08:46 Number of Shirts: 5 Number of Pants: 2 Number of Dresses: 3 The Total order is: $25.70 Amount Tended? 30 ==================================== -/- Georgetown Cleaning Services -/==================================== Customer: Peter Moonstruck Home Phone: (301) 728-8830 Order Date: Saturday, April 22, 2006 Order Time: 8:46 AM -----------------------------------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 -----------------------------------Total Order: $24.30 Tax Rate: 5.75 % Tax Amount: $1.40 Net Price: $25.70 -----------------------------------Amount Tended: $30.00 Difference: $4.30 ==================================== Press any key to continue . . .

10.

Close the DOS window

Exceptional Behaviors
C# 3.0 Practical Learning
454

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 the 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; class Program { static int Main() { double side; Console.WriteLine("Square Processing"); try { Console.Write("Enter Side: "); side = double.Parse(Console.ReadLine()); Console.WriteLine("\nSquare Characteristics"); Console.WriteLine("Side: {0}", side); Console.WriteLine("Perimeter: {0}", side * 4); } } } return 0;

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 section. Combined with the try 455 C# 3.0 Practical Learning

block, the syntax of an exception would be:
try {

// Try the program flow } catch { // Catch the exception }

A program that includes a catch section would appear as follows:
using System; public class Exercise { static int Main() { double Number; try {

Console.Write("Type a number: "); Number = double.Parse(Console.ReadLine());

Console.WriteLine("\n{0} * 2 = {1}", Number, Number * 2); } catch { } } } return 0;

Practical Learning: Introducing Vague Exceptions
1. To introduce exceptions, access the OrderProcessing.cs file and change it as follows:
using System; namespace GeorgetownCleaningServices5 { class OrderProcessing { . . . No Change public void ProcessOrder() { . . . No Change

C# 3.0 Practical Learning

456

// 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 } } }

2. Execute the application to test it 3. Close the DOS window

Exceptions and Custom Messages
C# 3.0 Practical Learning
457

As mentioned already, if an error occurs when processing the program in the try section, the compiler transfers 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; class Program { static int Main() { double side; Console.WriteLine("Square Processing"); try { Console.Write("Enter Side: "); side = double.Parse(Console.ReadLine()); Console.WriteLine("\nSquare Characteristics"); Console.WriteLine("Side: {0}", side); Console.WriteLine("Perimeter: {0}", side * 4); } catch { Console.WriteLine("There was a problem with the program"); } } } return 0;

Here is an error of running the program:
Square Processing Enter Side: w4 There was a problem with the program Press any key to continue . . .

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 OrderProcessing.cs file as follows:
using System; namespace GeorgetownCleaningServices5 { class OrderProcessing { . . . No Change public void ProcessOrder()

C# 3.0 Practical Learning

458

{ . . . 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 { 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 { Console.WriteLine("The value you typed for the number of " } . . . No Change try { Console.Write("Amount Tended? "); AmountTended = decimal.Parse(Console.ReadLine()); } catch { 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(); "dresses is not a valid number");

C# 3.0 Practical Learning

459

} }

private void ShowReceipt() { . . . No Change }

2. Execute the application to test it. 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 -----------------------------------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) ====================================

3. Close the DOS window

Exceptions in the .NET Framework
The Exception Class

C# 3.0 Practical Learning

460

In traditionally-oriented error dealing languages such as C/C++, Object Pascal, or Visual Basic, 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. Even 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, open 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 that describes the type of error that occurred. You can then access this Exception.Message property to display an error message if you want. Here is an example:
using System; class Program { static int Main() { double side; Console.WriteLine("Square Processing"); try {

C# 3.0 Practical Learning

461

Console.Write("Enter Side: "); side = double.Parse(Console.ReadLine()); Console.WriteLine("\nSquare Characteristics"); Console.WriteLine("Side: {0}", side); Console.WriteLine("Perimeter: {0}", side * 4);

} catch(Exception ex) { Console.WriteLine(ex.Message); } return 0; } }

Here is an example of running the program:
Square Processing Enter Side: Wer24 Input string was not in a correct format. Press any key to continue . . .

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; class Program { static int Main() { double side; Console.WriteLine("Square Processing"); try { Console.Write("Enter Side: "); side = double.Parse(Console.ReadLine()); Console.WriteLine("\nSquare Characteristics"); Console.WriteLine("Side: {0}", side); Console.WriteLine("Perimeter: {0}", side * 4);

} catch(Exception ex) { because " +

Console.WriteLine("The operation could not be carried "the number you typed is not valid");

C# 3.0 Practical Learning

462

} return 0; } }

Here is an example of running the program:
Square Processing Enter Side: 24.Gh The operation could not be carried because the number you typed is not valid Press any key to continue . . .

You can also combine the Exception.Message message and your own message:
using System; class Program { static int Main() { double side; Console.WriteLine("Square Processing"); try { Console.Write("Enter Side: "); side = double.Parse(Console.ReadLine()); Console.WriteLine("\nSquare Characteristics"); Console.WriteLine("Side: {0}", side); Console.WriteLine("Perimeter: {0}", side * 4);

" +

} catch(Exception ex) { Console.Write(ex.Message); Console.WriteLine( " Consequently, The operation could not be carried because } return 0; } "the number you typed is not valid");

}

Here is an example of running the program:
Square Processing Enter Side: 25.KL48 Input string was not in a correct format.. Consequently, The operation could not be carried because the number you typed is not valid Press any key to continue . . .

A Review of .NET Exception Classes
C# 3.0 Practical Learning
463

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 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

The FormatException Exception
When studying data formatting in Lesson 5, 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 an error. The error is of the FormatException class. Here is a program that deals with a FormatException exception:
using System; class Program { static int Main() { double side; Console.WriteLine("Square Processing"); try { Console.Write("Enter Side: "); side = double.Parse(Console.ReadLine()); Console.WriteLine("\nSquare Characteristics"); Console.WriteLine("Side: {0}", side); Console.WriteLine("Perimeter: {0}", side * 4); } catch(FormatException) { Console.WriteLine("\nYou typed an invalid number"); } } } return 0;

Here is an example of running the program:
Square Processing Enter Side: 25.9G

C# 3.0 Practical Learning

464

You typed an invalid number Press any key to continue . . .

Practical Learning: Using the FormatException Class
1. Change the OrderProcessing.cs file as follows (this includes the complete current version of the file):
using System; namespace GeorgetownCleaningServices5 { class OrderProcessing { #region Objects used to process an order // Price of items const decimal PriceOneShirt = 0.95M; const decimal PriceAPairOfPants = 2.95M; const decimal PriceOneDress = 4.55M; const decimal TaxRate = 0.0575M; // 5.75% CleaningOrderInfo cleaningOrder; // 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; #endregion #region Actions used to process and present an order public OrderProcessing() { cleaningOrder = new CleaningOrderInfo(); } public void ProcessOrder() { Console.WriteLine("-/- Georgetown Cleaning Services -/-"); // Request order information from the user Console.Write("Enter Customer Name: "); cleaningOrder.CustomerName = Console.ReadLine(); Console.Write("Enter Customer Phone: "); cleaningOrder.HomePhone = Console.ReadLine(); try {

Console.Write("Enter the order date(mm/dd/yyyy):

"); 465

C# 3.0 Practical Learning

cleaningOrder.OrderDate = DateTime.Parse(Console.ReadLine()); } catch (FormatException) { Console.WriteLine("The value you entered is not a valid date"); } try { Console.Write("Enter the order time(hh:mm AM/PM): "); cleaningOrder.OrderTime = DateTime.Parse(Console.ReadLine()); } catch { Console.WriteLine("The value you entered is not a valid time"); } // Request the quantity of each category of items try { Console.Write("Number of Shirts: "); cleaningOrder.NumberOfShirts = uint.Parse(Console.ReadLine()); if (cleaningOrder.NumberOfShirts < uint.MinValue) throw new OverflowException("Negative value not " "allowed for shirts"); } catch (FormatException) { Console.WriteLine("The value you typed for the number " + "shirts is not a valid number"); } try { Console.Write("Number of Pants: "); cleaningOrder.NumberOfPants = uint.Parse(Console.ReadLine()); } catch(FormatException) { Console.WriteLine("The value you typed for the number " + "pair or pants is not a valid number"); } try { Console.Write("Number of Dresses: "); cleaningOrder.NumberOfDresses = uint.Parse(Console.ReadLine()); } catch(FormatException) { Console.WriteLine("The value you typed for the number " + "dresses is not a valid number"); }

+

of

of

of

C# 3.0 Practical Learning

466

// Perform the necessary calculations SubTotalShirts = cleaningOrder.NumberOfShirts * PriceOneShirt; SubTotalPants = cleaningOrder.NumberOfPants * PriceAPairOfPants; SubTotalDresses = cleaningOrder.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 { 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() { Console.WriteLine(); // Display the receipt Console.WriteLine("===================================="); Console.WriteLine("-/- Georgetown Cleaning Services -/-"); Console.WriteLine("===================================="); Console.WriteLine("Customer: {0}", cleaningOrder.CustomerName); Console.WriteLine("Home Phone: {0}", cleaningOrder.HomePhone); Console.WriteLine("Order Date: {0:D}", cleaningOrder.OrderDate); Console.WriteLine("Order Time: {0:t}", cleaningOrder.OrderTime); Console.WriteLine("------------------------------------"); Console.WriteLine("Item Type Qty Unit/Price Sub-Total"); Console.WriteLine("------------------------------------"); Console.WriteLine("Shirts {0,3} {1,4} {2,6}", cleaningOrder.NumberOfShirts, PriceOneShirt, SubTotalShirts); Console.WriteLine("Pants {0,3} {1,4} {2,6}", cleaningOrder.NumberOfPants, PriceAPairOfPants, SubTotalPants);

C# 3.0 Practical Learning

467

Console.WriteLine("Dresses {0,3} {1,4} {2,6}", cleaningOrder.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("===================================="); } #endregion } }

2. Execute the application and test it. Here is an example:
-/- Georgetown Cleaning Services -/Enter Customer Name: Allen Dons Enter Customer Phone: 202-442-0400 Enter the order date(mm/dd/yyyy): 7/14/2005 Enter the order time(hh:mm AM/PM): 8:46 AM Number of Shirts: 5 Number of Pants: 2 Number of Dresses: 0 The Total order is: $11.26 Amount Tended? 15 ==================================== -/- Georgetown Cleaning Services -/==================================== Customer: Allen Dons Home Phone: 202-442-0400 Order Date: Thursday, July 14, 2005 Order Time: 8:46 AM -----------------------------------Item Type Qty Unit/Price Sub-Total -----------------------------------Shirts 5 0.95 4.75 Pants 2 2.95 5.90 Dresses 0 4.55 0.00 -----------------------------------Total Order: $10.65 Tax Rate: 5.75 % Tax Amount: $0.61 Net Price: $11.26 -----------------------------------Amount Tended: $15.00 Difference: $3.74 ====================================

C# 3.0 Practical Learning

468

Press any key to continue . . .

3. Close the DOS window

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 1 and 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 int 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); } return 0; }

When a value beyond the allowable range is asked to be stored in memory, the compiler produces (the expression 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) at System.Byte.Parse(String s) at Exercise.Main() in c:\programs\msvcs .net 2003\project17\exercise.cs:line 11

As with the other errors, when this exception is thrown, you should take an appropriate action.

The ArgumentOutOfRangeException Exception
C# 3.0 Practical Learning
469

Once again, when studying the techniques of converting or formatting values in Lesson 5, we saw that a value was 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 value, the compiler usually produces 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 int Main() { DateTime DateHired; Console.Write("Enter Date Hired: "); DateHired = DateTime.Parse(Console.ReadLine()); Console.WriteLine("Date Hired: {0:d}\n", DateHired); return 0; } }

If the user types a value that cannot be converted into a valid date, the compiler produces 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.

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 C# 3.0 Practical Learning
470

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 is performed, the compiler produces a DivideByZeroException exception.

C# 3.0 Practical Learning

471

Using Exception Handling
Techniques of Using Exceptions
Introduction
As mentioned in the previous lesson, the Exception class is equipped with a Message property that holds a string about the error that occurred. 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 class. To be able to receive custom messages, the Exception class provides the following constructor:
public Exception(string message);

Besides using this class or one of its derived classes in a catch clause, you can call this constructor to give a new and customized implementation of the exception.

Practical Learning: Using Exceptions
1. Start Microsoft Visual C# and create a new Console Application named
RealEstate3

2. To create a new class, in the Class View, right-click the name of the project, position the mouse on Add and click Class... 3. Set the Name to Property and press Enter 4. Change the file as follows:
using System; namespace RealEstate3 { public enum PropertyCondition { Unknown, Excellent, Good, NeedsRepair, BadShape }

C# 3.0 Practical Learning

472

public class Property { private string propNbr; private PropertyCondition cond; private short beds; private float baths; private int yr; private decimal val; public Property() { } public string PropertyNumber { get { return propNbr; } set { if (propNbr == "") propNbr = "N/A"; else propNbr = value; } } public PropertyCondition Condition { get { return cond; } set { cond = value; } } public short Bedrooms { get { if (beds <= 1) return 1; else return beds; } set { beds = value; } } public float Bathrooms { get{ return (baths <= 0) ? 0.00f : baths; } set { baths = value; } } public int YearBuilt { get { return yr; } set { yr = value; } } public decimal Value { get{ return (val <= 0) ? 0.00M : val; } set { val = value; }

C# 3.0 Practical Learning

473

} } }

5. On the main menu, click Project -> Add Class... 6. Set the Name to HouseType and press Enter 7. To derive a class, change the file as follows:
using System; namespace RealEstate3 { public class HouseType : Property { private short nbrOfStories; private bool basement; private bool garage; public short Stories { get { return nbrOfStories; } set { nbrOfStories = value; } } public bool FinishedBasement { get { return basement; } set { basement = value; } } public bool IndoorGarage { get { return garage; } set { garage = value; } }

} }

8. On the main menu, click Project -> Add -> Class... 9. Set the Name to Condominium and press Enter 10. To create another class based on the Property class, change the file as follows:
using System; namespace RealEstate3 { public class Condominium : Property { private bool handicap; public bool HandicapAccessible

C# 3.0 Practical Learning

474

{ get { return handicap; } set { handicap = value; } } } }

11. 12. To create a new class, in the Solution Explorer, right-click RealEstate3, position the mouse on Add and click Class... 13. Set the Name to PropertyListing and press Enter 14. Change the file as follows:

using System; namespace RealEstate3 { public enum PropertyType { Unknown, SingleFamily, Townhouse, Condominium } public class PropertyListing { private Property prop; private HouseType hse; private Condominium cond; private PropertyType tp; public Property ListProperty { get { return prop; } set { prop = value; } } public HouseType House { get { return hse; } set { hse = value; } } public Condominium Condo { get { return cond; } set { cond = value; } } public PropertyType Type { get { return tp; } set { tp = value; } }

C# 3.0 Practical Learning

475

public PropertyListing() { prop = new Property(); hse = new HouseType(); cond = new Condominium(); } public void CreateListing() { char answer = 'n'; short propType = 1; short condition = 1; Console.WriteLine(" =//= Altair Realty =//="); Console.WriteLine("-=- Property Creation -=-"); try { Console.WriteLine("\nTypes of Properties"); Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.WriteLine("4. Don't Know"); Console.Write("Enter Type of Property: "); propType = short.Parse(Console.ReadLine()); } catch (FormatException ex) { Console.WriteLine(ex.Message); } Console.Write("\nEnter Property #: "); ListProperty.PropertyNumber = Console.ReadLine(); try { Console.WriteLine("\nProperties Conditions"); Console.WriteLine("1. Excellent"); Console.WriteLine("2. Good (may need minor repair)"); Console.WriteLine("3. Needs Repair"); Console.Write("4. In Bad Shape (property needs "); Console.WriteLine("major repair or rebuild)"); Console.Write("Enter Property Condition: "); condition = short.Parse(Console.ReadLine()); } catch (FormatException ex) { Console.WriteLine(ex.Message); } if (condition == 1) ListProperty.Condition else if (condition == 2) ListProperty.Condition else if (condition == 3) ListProperty.Condition else if (condition == 4) ListProperty.Condition else ListProperty.Condition = PropertyCondition.Excellent; = PropertyCondition.Good; = PropertyCondition.NeedsRepair; = PropertyCondition.BadShape; = PropertyCondition.Unknown; 476

C# 3.0 Practical Learning

switch ((PropertyType)propType) { case PropertyType.SingleFamily: Type = PropertyType.SingleFamily; try { Console.Write("\nHow many stories (levels)? ");

House.Stories = short.Parse(Console.ReadLine());
} catch (FormatException ex) { Console.WriteLine(ex.Message); } try { Console.Write( "Does it have an indoor car garage (y/n): "); answer = char.Parse(Console.ReadLine()); if ((answer == 'y') || (answer == 'Y')) House.IndoorGarage = true; else House.IndoorGarage = false; } catch (FormatException) { Console.WriteLine("Invalid Indoor Car Garage Answer"); } try { Console.Write("Is the basement finished(y/n): "); answer = char.Parse(Console.ReadLine()); if ((answer == 'y') || (answer == 'Y')) House.FinishedBasement = true; else House.FinishedBasement = false; } catch (FormatException) { Console.WriteLine("Invalid Basement Answer"); } break; case PropertyType.Townhouse: Type = PropertyType.Townhouse; try { Console.Write("\nHow many stories (levels)? "); House.Stories = short.Parse(Console.ReadLine()); } catch (FormatException ex) { Console.WriteLine(ex.Message); } Console.Write("Does it have an indoor car garage answer = char.Parse(Console.ReadLine());

(y/n): ");

C# 3.0 Practical Learning

477

if ((answer == 'y') || (answer == 'Y')) House.IndoorGarage = true; else House.IndoorGarage = false; Console.Write("Is the basement finished(y/n): "); answer = char.Parse(Console.ReadLine()); if ((answer == 'y') || (answer == 'Y')) House.FinishedBasement = true; else House.FinishedBasement = false; break; case PropertyType.Condominium: Type = PropertyType.Condominium; Console.Write( "\nIs the building accessible to handicapped (y/n): answer = char.Parse(Console.ReadLine()); if ((answer == 'y') || (answer == 'Y')) Condo.HandicapAccessible = true; else Condo.HandicapAccessible = false; break; default: Type = PropertyType.Unknown; break; } try { Console.Write("\nHow many bedrooms? "); ListProperty.Bedrooms = short.Parse(Console.ReadLine()); } catch (FormatException ex) { Console.WriteLine(ex.Message); } try { Console.Write("How many bathrooms? "); ListProperty.Bathrooms = float.Parse(Console.ReadLine()); } catch (FormatException ex) { Console.WriteLine(ex.Message); } try { Console.Write("Year built: "); ListProperty.YearBuilt = int.Parse(Console.ReadLine()); } catch (FormatException ex) { Console.WriteLine(ex.Message); } try { Console.Write("Property Value: "); ListProperty.Value = decimal.Parse(Console.ReadLine());

");

C# 3.0 Practical Learning

478

} catch (FormatException ex) { Console.WriteLine(ex.Message); } } public void ShowProperty() { Console.WriteLine("=================================="); Console.WriteLine(" =//=//= Altair Realty =//=//="); Console.WriteLine("-=-=-=- Properties Listing -=-=-=-"); Console.WriteLine("----------------------------------"); Console.WriteLine("Property #: {0}", ListProperty.PropertyNumber); Console.WriteLine("Property Type: {0}", Type); switch (Type) { case PropertyType.SingleFamily: case PropertyType.Townhouse: Type = PropertyType.SingleFamily; Console.WriteLine("Stories: {0}", House.Stories); Console.WriteLine("Has Indoor Car Garage: {0}", House.IndoorGarage); Console.WriteLine("Finished Basement: {0}", House.FinishedBasement); break; case PropertyType.Condominium: Console.WriteLine("Handicapped Accessible Building: Condo.HandicapAccessible); break; } Console.WriteLine("Condition: ListProperty.Condition); Console.WriteLine("Bedrooms: ListProperty.Bedrooms); Console.WriteLine("Bathrooms: ListProperty.Bathrooms); Console.WriteLine("Year Built: ListProperty.YearBuilt); Console.WriteLine("Market Value: ListProperty.Value); } } } {0}", {0}", {0}", {0}", {0:C}",

{0}",

15.

Access the Program.cs file and change it as follows:

using System; namespace RealEstate3 { public static class Program {

C# 3.0 Practical Learning

479

static int Main() { PropertyListing listing = new PropertyListing(); listing.CreateListing(); Console.WriteLine("\n"); listing.ShowProperty(); Console.WriteLine(); return 0; } } }

16.

Execute the application and test it. Here is an example:

=//= Altair Realty =//= -=- Property Creation -=Types of Properties 1. Single Family 2. Townhouse 3. Condominium 4. Don't Know Enter Type of Property: 1 Enter Property #: 276744 Properties Conditions 1. Excellent 2. Good (may need minor repair) 3. Needs Repair 4. In Bad Shape (property needs major repair or rebuild) Enter Property Condition: 3 How many stories (levels)? -2 Does it have an indoor car garage (y/n): g Is the basement finished(y/n): m How many bedrooms? How many bathrooms? Year built: Property Value: -5 3684634 87324 2

================================== =//=//= Altair Realty =//=//= -=-=-=- Properties Listing -=-=-=---------------------------------Property #: 276744 Property Type: SingleFamily Stories: -2 Has Indoor Car Garage: False Finished Basement: False Condition: NeedsRepair Bedrooms: 1 Bathrooms: 3684634 Year Built: 87324 Market Value: $2.00

C# 3.0 Practical Learning

480

Press any key to continue . . .

17.

Close the DOS window

Throwing an Exception
When a bad behavior occurs in your application, the program is said to throw an exception. Your job is to know, as much as possible, when and why this would happen. In the previous lesson and in the above section, we saw that, when an application throws an exception, you could display your own message. To effectively address a particular exception, you need to identify the (exact, if possible) section of code where the exception would occur and you should know why the error would be produced. After identifying the area in code where an exception is likely to occur, you can further customize the behavior of your application. To customize the throwing of an exception, in the section of code where you are anticipating the error, type the throw keyword followed by a new instance of the Exception class (or one of its derived classes) using the constructor that takes a string. Here is an example:
using System; class Program { static int Main() { double Operand1, Operand2; double Result = 0.00; char Operator; Console.WriteLine( "This program allows you to perform an operation on two numbers"); try { Console.Write("Enter a number: "); Operand1 = double.Parse(Console.ReadLine()); Console.Write("Enter an operator: "); Operator = char.Parse(Console.ReadLine()); Console.Write("Enter a number: "); Operand2 = double.Parse(Console.ReadLine()); if (Operator != '+' && Operator != '-' && Operator != '*' && Operator != '/') throw new Exception(Operator.ToString()); switch (Operator) { case '+':

C# 3.0 Practical Learning

481

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); } return 0; } }

Here is an example of running the program:
This program allows you to perform an operation on two numbers Enter a number: 124.55 Enter an operator: & Enter a number: 36.85 Operation Error: & is not a valid operator Press any key to continue . . .

Practical Learning: Throwing an Exception
1. Access the PropertyListing.cs file 2. To throw some exceptions, change the file as follows:
using System; namespace RealEstate3 { public enum PropertyType { Unknown, SingleFamily,

C# 3.0 Practical Learning

482

}

Townhouse, Condominium

class PropertyListing { . . . No Change public void CreateListing() { . . . No Change switch ((PropertyType)propType) { case PropertyType.SingleFamily: Type = PropertyType.SingleFamily; try { Console.Write("\nHow many stories (levels)? "); House.Stories = short.Parse(Console.ReadLine()); if (House.Stories < 1) { House.Stories = 1; throw new OverflowException( "The number of stories must be positive"); } } catch (OverflowException ex) { Console.WriteLine(ex.Message); } . . . No Change break; case PropertyType.Townhouse: Type = PropertyType.Townhouse; try { Console.Write("\nHow many stories (levels)? "); House.Stories = short.Parse(Console.ReadLine()); if (House.Stories < 1) { House.Stories = 1; throw new OverflowException( "The number of stories must be positive"); } } catch (OverflowException ex) { Console.WriteLine(ex.Message); } . . . No Change } . . . No Change

C# 3.0 Practical Learning

483

} public void ShowProperty() { . . . No Change }

} }

3. Execute the application and test it. Here is an example:
=//= Altair Realty =//= -=- Property Creation -=Types of Properties 1. Single Family 2. Townhouse 3. Condominium 4. Don't Know Enter Type of Property: 2 Enter Property #: 463864 Properties Conditions 1. Excellent 2. Good (may need minor repair) 3. Needs Repair 4. In Bad Shape (property needs major repair or rebuild) Enter Property Condition: 3 How many stories (levels)? -3 The number of levels must be positive Does it have an indoor car garage (y/n): G Is the basement finished(y/n): K How many bedrooms? How many bathrooms? Year built: Property Value: -4 -2 2994 425885

================================== =//=//= Altair Realty =//=//= -=-=-=- Properties Listing -=-=-=---------------------------------Property #: 463864 Property Type: Townhouse Stories: 1 Has Indoor Car Garage: False Finished Basement: False Condition: NeedsRepair Bedrooms: 1 Bathrooms: 0.00 Year Built: 2994 Market Value: $425,885.00 Press any key to continue . . .

4. Close the DOS window C# 3.0 Practical Learning
484

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 } 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 catch. 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 previous program. That 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 as 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. Obviously various bad things could happen when this program is running. To handle the exceptions that this program could produce, you can 485 C# 3.0 Practical Learning

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 Program { static int Main() { double Operand1, Operand2; double Result = 0.00; char Operator; Console.WriteLine("This program allows you to perform an operation on two numbers"); try { Console.Write("Enter a number: "); Operand1 = double.Parse(Console.ReadLine()); Console.Write("Enter an operator: "); Operator = char.Parse(Console.ReadLine()); Console.Write("Enter a number: "); Operand2 = double.Parse(Console.ReadLine()); if (Operator != '+' && 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; }

C# 3.0 Practical Learning

486

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); } } } return 0;

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. 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, probably the best option 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. Here is an example that catches two types of exceptions:
using System; class Program { static int Main() { double Operand1, Operand2; double Result = 0.00; char Operator; Console.WriteLine("This program allows you to perform an operation on two numbers"); try { Console.Write("Enter a number: "); Operand1 = double.Parse(Console.ReadLine()); Console.Write("Enter an operator: "); Operator = char.Parse(Console.ReadLine()); Console.Write("Enter a number: "); Operand2 = double.Parse(Console.ReadLine()); if (Operator != '+' && Operator != '-' && Operator != '*' && Operator != '/') throw new Exception(Operator.ToString()); if (Operator == '/') if (Operand2 == 0) throw new DivideByZeroException("Division by zero is not

allowed");

C# 3.0 Practical Learning

487

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 (DivideByZeroException ex) { Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine("\nOperation Error: {0} is not a valid operator", ex.Message); } } } return 0;

When running this program, if the user types a wrong operator, the compiler gets out of 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: Catching Various Exceptions
1. Change the PropertyListing.cs file as follows:
using System;

C# 3.0 Practical Learning

488

namespace RealEstate3 { public enum PropertyType { Unknown, SingleFamily, Townhouse, Condominium } class PropertyListing { private Property prop; private HouseType hse; private Condominium cond; private PropertyType tp; public Property ListProperty { get { return prop; } set { prop = value; } } public HouseType House { get { return hse; } set { hse = value; } } public Condominium Condo { get { return cond; } set { cond = value; } } public PropertyType Type { get { return tp; } set { tp = value; } } public PropertyListing() { prop = new Property(); hse = new HouseType(); cond = new Condominium(); } public void CreateListing() { char answer = 'n'; short propType = 1; short condition = 1; Console.WriteLine(" =//= Altair Realty =//="); Console.WriteLine("-=- Property Creation -=-"); try { Console.WriteLine("\nTypes of Properties");

C# 3.0 Practical Learning

489

number");

} catch (FormatException) { Console.WriteLine("The value you entered is not a valid } catch (Exception) { Console.WriteLine("Something bad happened and we don't like

Console.WriteLine("1. Single Family"); Console.WriteLine("2. Townhouse"); Console.WriteLine("3. Condominium"); Console.WriteLine("4. Don't Know"); Console.Write("Enter Type of Property: "); propType = short.Parse(Console.ReadLine());

it");

} Console.Write("\nEnter Property #: "); ListProperty.PropertyNumber = Console.ReadLine(); try { Console.WriteLine("\nProperties Conditions"); Console.WriteLine("1. Excellent"); Console.WriteLine("2. Good (may need minor repair)"); Console.WriteLine("3. Needs Repair"); Console.Write("4. In Bad Shape (property needs "); Console.WriteLine("major repair or rebuild)"); Console.Write("Enter Property Condition: "); condition = short.Parse(Console.ReadLine());

} catch (FormatException) { Console.WriteLine("The value you typed for the property condition is not good"); } catch (Exception) { Console.WriteLine("Something unacceptable has just happened"); } if (condition == 1) ListProperty.Condition else if (condition == 2) ListProperty.Condition else if (condition == 3) ListProperty.Condition else if (condition == 4) ListProperty.Condition else ListProperty.Condition = PropertyCondition.Excellent; = PropertyCondition.Good; = PropertyCondition.NeedsRepair; = PropertyCondition.BadShape; = PropertyCondition.Unknown;

switch ((PropertyType)propType) { case PropertyType.SingleFamily: Type = PropertyType.SingleFamily; try {

C# 3.0 Practical Learning

490

Console.Write("\nHow many stories (levels)? "); House.Stories = short.Parse(Console.ReadLine()); if (House.Stories < 1) { House.Stories = 1; throw new OverflowException("The number of levels must be positive"); } } catch (OverflowException ex) { Console.WriteLine(ex.Message); } catch (FormatException) { Console.WriteLine("The number you entered for the stories is not allowed"); } catch (Exception) { Console.WriteLine("This is one of those abnormal behaviors"); } try { Console.Write("Does it have an indoor car garage (y/n): "); answer = char.Parse(Console.ReadLine()); if ((answer == 'y') || (answer == 'Y')) House.IndoorGarage = true; else House.IndoorGarage = false;

Answer");

} catch (FormatException) { Console.WriteLine("Invalid Indoor Car Garage } try { Console.Write("Is the basement finished(y/n): "); answer = char.Parse(Console.ReadLine()); if ((answer == 'y') || (answer == 'Y')) House.FinishedBasement = true; else House.FinishedBasement = false; } catch (FormatException) { Console.WriteLine("Invalid Basement Answer"); } break; case PropertyType.Townhouse: Type = PropertyType.Townhouse; try {

C# 3.0 Practical Learning

491

Console.Write("\nHow many stories (levels)? "); House.Stories = short.Parse(Console.ReadLine()); if (House.Stories < 1) { House.Stories = 1; throw new OverflowException("The number of levels must be positive"); } } catch (OverflowException ex) { Console.WriteLine(ex.Message); } catch (FormatException) { Console.WriteLine("The number you entered for the stories is not allowed"); } catch (Exception) { Console.WriteLine("This is one of those abnormal behaviors"); } (y/n): "); Console.Write("Does it have an indoor car garage answer = char.Parse(Console.ReadLine()); if ((answer == 'y') || (answer == 'Y')) House.IndoorGarage = true; else House.IndoorGarage = false; Console.Write("Is the basement finished(y/n): "); answer = char.Parse(Console.ReadLine()); if ((answer == 'y') || (answer == 'Y')) House.FinishedBasement = true; else House.FinishedBasement = false; break; case PropertyType.Condominium: Type = PropertyType.Condominium; Console.Write("\nIs the building accessible to handicapped (y/n): "); answer = char.Parse(Console.ReadLine()); if ((answer == 'y') || (answer == 'Y')) Condo.HandicapAccessible = true; else Condo.HandicapAccessible = false; break; default: Type = PropertyType.Unknown; break;

} try {

Console.Write("\nHow many bedrooms? "); ListProperty.Bedrooms = short.Parse(Console.ReadLine());

C# 3.0 Practical Learning

492

} catch (FormatException) { Console.WriteLine( "The value you entered for the number of bedrooms is not acceptable"); } catch (Exception) { Console.WriteLine("The program has decided to stop"); } try {

} catch (FormatException) { Console.WriteLine("The value you decided to enter for the bedrooms is rejected"); } catch (Exception) { Console.WriteLine("The computer doesn't like what is going on"); } try {

Console.Write("How many bathrooms? "); ListProperty.Bathrooms = float.Parse(Console.ReadLine());

} catch (FormatException) { Console.WriteLine("You didn't enter a valid number for the year built"); } catch (Exception) { Console.WriteLine("Whatever, whatever, whatever"); } try {

Console.Write("Year built: "); ListProperty.YearBuilt = int.Parse(Console.ReadLine());

} catch (FormatException) { Console.WriteLine( "The value of a property must be a good decimal number"); } catch (Exception) { Console.WriteLine( "This is where the application draws the line: it stops!"); } } public void ShowProperty()

Console.Write("Property Value: "); ListProperty.Value = decimal.Parse(Console.ReadLine());

C# 3.0 Practical Learning

493

{ Console.WriteLine("=================================="); Console.WriteLine(" =//=//= Altair Realty =//=//="); Console.WriteLine("-=-=-=- Properties Listing -=-=-=-"); Console.WriteLine("----------------------------------"); Console.WriteLine("Property #: {0}", ListProperty.PropertyNumber); Console.WriteLine("Property Type: {0}", Type); switch (Type) { case PropertyType.SingleFamily: case PropertyType.Townhouse: Type = PropertyType.SingleFamily; Console.WriteLine("Stories: {0}", House.Stories); Console.WriteLine("Has Indoor Car Garage: {0}", House.IndoorGarage); Console.WriteLine("Finished Basement: {0}", House.FinishedBasement); break; case PropertyType.Condominium: Console.WriteLine("Handicapped Accessible Building: Condo.HandicapAccessible); break; } Console.WriteLine("Condition: ListProperty.Condition); Console.WriteLine("Bedrooms: ListProperty.Bedrooms); Console.WriteLine("Bathrooms: ListProperty.Bathrooms); Console.WriteLine("Year Built: ListProperty.YearBuilt); Console.WriteLine("Market Value: ListProperty.Value); } } } {0}", {0}", {0:F}", {0}", {0:C}",

{0}",

2. Execute the application and test it. Here is an example:
=//= Altair Realty =//= -=- Property Creation -=Types of Properties 1. Single Family 2. Townhouse 3. Condominium 4. Don't Know Enter Type of Property: 1 Enter Property #: 228046 Properties Conditions 1. Excellent

C# 3.0 Practical Learning

494

2. Good (may need minor repair) 3. Needs Repair 4. In Bad Shape (property needs major repair or rebuild) Enter Property Condition: 4 How many stories (levels)? -5 The number of levels must be positive Does it have an indoor car garage (y/n): y Is the basement finished(y/n): Not at all Invalid Basement Answer How many bedrooms? Apparently 3 or 4 The value you entered for the number of bedrooms is not acceptable How many bathrooms? 1 can flush, the owner is working on another The value you decided to enter for the bedrooms is rejected Year built: Around 1962 You didn't enter a valid number for the year built Property Value: A little over 420000 The value of a property must be an good decimal number ================================== =//=//= Altair Realty =//=//= -=-=-=- Properties Listing -=-=-=---------------------------------Property #: 228046 Property Type: SingleFamily Stories: 1 Has Indoor Car Garage: True Finished Basement: False Condition: BadShape Bedrooms: 1 Bathrooms: 0.00 Year Built: 0 Market Value: $0.00 Press any key to continue . . .

3. Close the DOS window

Exception Nesting
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, or 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, C# 3.0 Practical Learning
495

make sure you include an appropriate throw in the try block. Here is an example:
using System; class Program { static int Main() { double Operand1, Operand2; double Result = 0.00; char Operator; Console.WriteLine( "This program allows you to perform an operation on two numbers"); try { Console.Write("Enter a number: "); Operand1 = double.Parse(Console.ReadLine()); Console.Write("Enter an operator: "); Operator = char.Parse(Console.ReadLine()); Console.Write("Enter a number: "); 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; case '*': Result = Operand1 * Operand2; Console.WriteLine("\n{0} * {1} = {2}", Operand1, Operand2, Result); break; case '/': // The following exception is nested in the previous try { if (Operand2 == 0) throw new DivideByZeroException("Division by zero is not allowed");

try

C# 3.0 Practical Learning

496

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); } return 0; } }

Here is an example of running the program:
This program allows you to perform an operation on two numbers Enter a number: 324.53 Enter an operator: / Enter a number: 0 Division by zero is not allowed Press any key to continue . . .

Exceptions and Methods
One of the most effective techniques used to deal with code is to isolate assignments. We 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 Program { static int Main() { double Number1, Number2; double Result = 0.00; char Operator; Console.WriteLine( "This program allows you to perform an operation on two numbers"); try {

Console.WriteLine("To proceed, enter"); Console.Write("First Number: "); Number1 = double.Parse(Console.ReadLine());

C# 3.0 Practical Learning

497

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"); 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); } } return 0;

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;

C# 3.0 Practical Learning

498

} }

Here is one example of running the program:
This program allows you to perform an operation on two numbers To proceed, enter First Number: 248.84 An Operator (+, -, * or /): * Second Number: 57.93 248.84 * 57.93 = 14415.3012 Press any key to continue . . .

Here is another example of running the program:
This program allows you to perform an operation on two numbers To proceed, enter First Number: 12.55 An Operator (+, -, * or /): [ Operation Error: [ is not a valid operator Press any key to continue . . .

You can still use regular methods along with methods that handle exceptions. As done in Main(), 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 method:
using System; class Program { static int Main() { double Number1, Number2; double Result = 0.00; char Operator; Console.WriteLine( "This program allows you to perform an operation on two numbers"); 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);

C# 3.0 Practical Learning

499

} 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); } return 0; } static double Calculator(double Value1, double Value2, char Symbol) { double Result = 0.00; switch (Symbol) { case '+': Result = Value1 + Value2; Console.WriteLine("\n{0} + {1} = {2}", Value1, Value2, break; case '-': Result = Value1 - Value2; Console.WriteLine("\n{0} - {1} = {2}", Value1, Value2, break; case '*': Result = Value1 * Value2; Console.WriteLine("\n{0} * {1} = {2}", Value1, Value2, 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;

Result);

Result);

Result);

} }

return Result;

C# 3.0 Practical Learning

500

}

Isolating assignments and handing them to method is an important matter in the area of application programming. Consider a program that handles a simple exception such as this one:
using System; class Program { static int 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.Write("Enter a number: "); Number1 = double.Parse(Console.ReadLine()); Console.Write("Enter a number: "); 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); } catch (DivideByZeroException ex) { Console.WriteLine(ex.Message); } return 0; } }

One of the ways you can use methods in exception routines is to have a central method that receives variables, and sends them to other external methods. 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 Program { static int Main() { double Number1, Number2;

C# 3.0 Practical Learning

501

Console.WriteLine("This program allows you to perform a division of two numbers"); try { Console.Write("Enter a number: "); Number1 = double.Parse(Console.ReadLine()); Console.Write("Enter a number: "); Number2 = double.Parse(Console.ReadLine()); Division(Number1, Number2); } catch(DivideByZeroException ex) { Console.WriteLine(ex.Message); } } return 0;

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 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.

Custom Exceptions
Introduction
As seen in the previous lesson and in the above sections, exception handling is a great part of the .NET Framework. As high as it is supported by various classes of the .NET, it is possible that you want to further customize the handling of exceptions in your application. One way you can do this is to create your own exception class.

Creating an Exceptional Class
C# 3.0 Practical Learning
502

The Exception class of the .NET Framework is a great tool for handling exceptions in a C# application. To deal with particular errors, various classes are derived from Exception. If for some reason the Exception class and none of the Exception-based classes fulfills your requirement, you can derive a new class from Exception or from one of the available Exception-based classes. To derive a class from Exception or from one of its classes, simply follow the rules we reviewed from class inheritance. Here is an example of a class based on Exception:
public class CustomException : Exception { }

There is no real rule to follow as to what class to derive from but it may be a good idea to derive your class from one that already addresses your issue but not the way you want. For example, if you want to create a class that would process numeric values but you think the FormatException class is not doing what you want, you can derive your class from FormatException. After deriving the class, you can add the necessary members as you see fit. Remember that the primary characteristic of an exception is to present a message to the user. In Exception-based classes, this message is represented by the Message property. Therefore, if you want to prepare a custom message for your class, you can override or new this property. Here is an example:
public class IntegerException : Exception { public override string Message { get { return "The value you entered is not a valid integer"; } } }

Once you have created and customized your exceptional class, you can use it the same way you would another exception class, such as throwing it. Here is an example
using System; public class DigitException : Exception { private char c; public DigitException(char x) { c = x; } public override string Message { get { return "The character you entered is not a valid digit"; }

C# 3.0 Practical Learning

503

} } class Program { static int Main() { try { char chNumber = '0'; Console.Write("Enter a digit (0 to 9): "); chNumber = char.Parse(Console.ReadLine()); if ((chNumber != '0') && (chNumber != '1') && (chNumber != '2') && (chNumber != '3') && (chNumber != '4') && (chNumber != '5') && (chNumber != '6') && (chNumber != '7') && (chNumber != '8') && (chNumber != '9')) throw new DigitException(chNumber); Console.WriteLine("Number: {0}\n", chNumber); } catch (DigitException ex) { Console.WriteLine(ex.Message); } catch (FormatException ex) { Console.WriteLine(ex.Message); } catch (Exception ex) { Console.WriteLine(ex.Message); } } } return 0;

Here is an example of running the program:
Enter a digit (0 to 9): 8 Number: 8 Press any key to continue . . .

Here is another example of running the program:
Enter a digit (0 to 9): w The character you entered is not a valid digit Press any key to continue . . .

C# 3.0 Practical Learning

504

C# 3.0 Practical Learning

505

Introduction to Arrays
A Series of Similar Items
Introduction
Imagine you want to create a program that would use a series of numbers. In algebra, we represent such a series as follows: X1, X2, X3, X4, X5. You can also represent a list of names as follows: Alex Gaston Hermine Jerry 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; public class Exercise { static int Main() { var Number1 = var Number2 = var Number3 = var Number4 = var Number5 = } } return 0;

12.44; 525.38; 6.28; 2448.32; 632.04;

Instead of using individual variables that share the same characteristics, you can group them in an entity like a regular variable. This group is called an array. Therefore, an array is a series of items of the same kind. It could be a C# 3.0 Practical Learning
506

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

Start Microsoft Visual C# and create a Console Application named
VideoCollection1

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 control? This information allows the compiler to know how much space each item of the group will require. This is because each item 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 each item that makes up the series, you must use a common name to identify them. The name is simply the same type of name 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]. An array is considered a reference type. Therefore, an array requests its memory using the new operator. Based on this, one of the formulas to declare an array is:
DataType[] VariableName = new DataType[Number];

Alternatively, you can use the var keyword to create an array. The formula to use would be:
var VariableName = new DataType[Number];

In these formulas, the DataType factor can be one of the types we have used so far (char, int, float, double, decimal, string, etc). It can also be the name of a class as we will learn in Lesson 23. Like a normal variable, an array must have a name, represented in our formula as VariableName. 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. 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; public class Exercise

C# 3.0 Practical Learning

507

{ static void Main() { double numbers = new double[5]; } }

Using the var keyword, this array can also be declared as follows:
using System; public class Exercise { static void Main() { var Numbers = new double[5]; } }

Practical Learning: Creating an Array
1. To create arrays, change the Programs.cs file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace VideoCollection1 { public class Program { static void Main(string[] args) { long[] ShelfNumbers = new long[10]; string[] Titles = new string[10]; string[] Directors = new string[10]; int[] Lengths = new int[10]; string[] Ratings = new string[10]; double[] Prices = new double[10]; } } }

2. Save the file

Introduction to Initializing an Array
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 or an element 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.

C# 3.0 Practical Learning

508

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 algebra, 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 can be referred to by an incremental number called an index. A C# (like a C/C++) array is zero-based. This means that the first member of the array has an index of 0, the second has an index of 1, and so on. In algebra, 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; public class Exercise { static void Main() { var Numbers = new double[5]; Numbers[0] Numbers[1] Numbers[2] Numbers[3] Numbers[4] } } = = = = = 12.44; 525.38; 6.28; 2448.32; 632.04;

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; public class Exercise { static void Main() { var Numbers = new double[5] { 12.44, 525.38, 6.28, 2448.32, 632.04 }; } }

If you use this second technique, you don't have to specify the number of items in the series. In this case, you can leave all square brackets empty:
using System; public class Exercise

C# 3.0 Practical Learning

509

{ static void Main() { var Numbers = new double[] { 12.44, 525.38, 6.28, 2448.32, 632.04 }

}; }

If you leave the square brackets empty, the compiler will figure out the number of items.

Practical Learning: Initializing Some Arrays
1. To initialize the arrays, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace VideoCollection1 { class Program { static void Main(string[] args) { long[] ShelfNumbers = new long[] { 2985, 8024, 5170, 1304, 9187, 1193, 3082, 8632, 4633, 9623 }; string[] Titles = new string[] { "The Distinguished Gentleman", "A Perfect Murder", "Chalte Chalte", "Ransom", "Not Another Teen Movie", "Madhubaala", "Get Shorty", "Sneakers", "Born Invincible", "Hush" }; string[] Directors = new string[] { "Jonathan Lynn", "Andrew Davis", "Aziz Mirza", "Ron Howard", "Joel Gallen", "Shivram Yadav", "Barry Sonnenfeld", "Paul Alden Robinson", "Unknown", "Jonathan Darby" }; int[] Lengths = new int[] { 112, 108, 145, 121, 100, 0, 105, 126, 90, 96 }; string[] Ratings = new string[] { "R", "R", "N/R", "R", "Unrated", "N/R", "R", "PG-13", "N/R", "PG-13" }; double[] Prices = new double[] { 14.95D, 19.95D, 22.45D, 14.95D, 9.95D,

C# 3.0 Practical Learning

510

17.50D, } } } };

9.95D,

9.95D,

5.95D, 8.75D

2. Save the file

Other Techniques of Initializing an Array
We have initialized our arrays so far with values we specified directly in the curly brackets. If you have declared and initialized some variables of the same type, you can use them to initialize an array. Here is an example:
using System; public class Exercise { static void Main() { var Area = 97394.2204D; var Distance = 982.84D; var Level = 27D; var Quantity = 237957.704D; var Measures = new double[] { Area, Distance, Level, Quantity }; } }

The values can also come from constant variables. Here is an example:
using System; public class Exercise { static void Main() { const double PI = 3.141592653; var SqureRootOf2 = 1.414D; var e = 2.718D; const double RadiusOfEarth = 6370; // km var ln2 = 0.6931; ln2 }; } } var Measures = new double[] { PI, SqureRootOf2, e, RadiusOfEarth,

The values can also come from calculations, whether the calculation is from an initialized variable or made locally in the curly brackets. Here is an example:
using System; public class Exercise { static void Main()

C# 3.0 Practical Learning

511

{ const double DensityOfWater = 1000; // kg/m3 ; var MassOfEarth = 5.98 * 10e24; // kg var EarthMoonDistance = 2.39 * 10e5; // miles var Measures = new double[] { DensityOfWater, 9.30 * 10.7, MassOfEarth, EarthMoonDistance }; } }

The rule to follow is that, at the time the array is created, the compiler must be able to know exactly the value of each member of the array, no guessing. All of the arrays we have declared so far were using only numbers. The numbers we used were decimal constants. If the array is made of integers, you can use decimal, hexadecimal values, or a combination of both. Here is an example:
using System; public class Exercise { static void Main() { var Red = 0xFF0000; var SomeColor = 0x800000; var Colors = new int[] { 2510, Red, 818203, SomeColor, 0xF28AC }; } }

An array can have types of values of any of the data types we have used so far. The rule to follow is that all members of the array must be of the same type. For example, you can declare an array of Boolean values, as long as all values can be evaluated to true or false. Here is an example:
using System; public class Exercise { static void Main() { var FullTimeStudents = new bool[] { true, true, true, false, true, false }; } }

As stated already, each values of a Boolean array must be evaluated to true or false. This means that you can use variables or expressions as members of the array. Here is an example:
using System; public class Exercise { static void Main() { var House1Value = 460885.85D;

C# 3.0 Practical Learning

512

var House2Value = 685770.00D; var Conparisons = new bool[] { 25 < 10, House1Value == House2Value, true }; } }

As we will see when studying arrays and classes, you can use this technique to create an array of dates, times, or date and time values. Here is an example:
using System; public class Exercise { static void Main() { var DateHired = new DateTime(1998, 10, 08); var IndependenceDay = new DateTime(1960, 1, 1); } } var Dates = new DateTime[] { DateHired, IndependenceDay };

Accessing the Members of an Array
Introduction
After initializing an array, which means after each of its members has been given a value, you can access a member of the array to get, manipulate or even change its value. To access a member of the array, you use the square brackets as we saw above. As done for normal variables, one of the reasons of accessing a member of an array would be to display its value on the console screen, which can be done by passing it to a Console.Write() or a Console.WriteLine() method. Here is an example:
using System; public class Exercise { static int Main() { var Numbers = new double[] { 12.44, 525.38, 6.28, 2448.32, 632.04 }; Console.Write(Numbers[3]); } } return 0;

In the same way, you can use the curly brackets notation to display the value of a member:
using System;

C# 3.0 Practical Learning

513

public class Exercise { static int Main() { var Numbers = new double[] { 12.44, 525.38, 6.28, 2448.32, 632.04 }; Console.Write("Number: {0} ", Numbers[3]); } } return 0;

In the same way, you can access 1, a few or all members of the array.

Practical Learning: Using the Members of an Array
1. To show the values of a member of an array, change the Program.cs file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace VideoCollection1 { class Program { static void Main(string[] args) { long[] ShelfNumbers = new long[] { 2985, 8024, 5170, 1304, 9187, 1193, 3082, 8632 }; . . . No Change double[] Prices = new double[] { 14.95D, 19.95D, 22.45D, 14.95D, 9.95D, 17.50D, 9.95D, 9.95D, 5.95D, 8.75D }; Console.WriteLine("==============================="); Console.WriteLine("Video Information"); Console.WriteLine("-------------------------------"); Console.WriteLine("Shelf #: {0}", ShelfNumbers[1]); Console.WriteLine("Title: {0}", Titles[1]); Console.WriteLine("Director: {0}", Directors[1]); Console.WriteLine("Length: {0} minutes", Lengths[1]); Console.WriteLine("Rating: {0}", Ratings[1]); Console.WriteLine("Price: {0}", Prices[1]); Console.WriteLine("===============================");

} } }

C# 3.0 Practical Learning

514

2. Execute the application and test it. Here is an example:
=============================== Video Information ------------------------------Shelf #: 8024 Title: A Perfect Murder Director: Andrew Davis Length: 108 minutes Rating: R Price: 19.95 =============================== Press any key to continue . . .

3. Close the DOS window

For an Indexed Member of the Array
We saw how you can use the square brackets to access each member of the array one at a time. That technique allows you to access one, a few, or each member. If you plan to access all members of the array instead of just one or a few, you can use the for loop. The formula to follow is:
for(DataType Initializer; EndOfRange; Increment) Do What You Want;

In this formula, the for keyword, the parentheses, and the semi-colons are required. The DataType factor is used to specify how you will count the members of the array. The Initializer specifies how you would indicate the starting of the count. As seen in Lesson 12, this initialization could use an initialized int-based variable. The EndOfRange specifies how you would stop counting. If you are using an array, it should combine a conditional operation (<, <=, >, >=, or !=) with the number of members of the array minus 1. The Increment factor specifies how you would move from one index to the next. Here is an example:
using System; public class Exercise { static int Main() { var Numbers = new double[] { 12.44, 525.38, 6.28, 2448.32, 632.04 }; for (var i = 0; i < 5; i++) Console.WriteLine(Numbers[i]); } } return 0;

C# 3.0 Practical Learning

515

This would produce:
12.44 525.38 6.28 2448.32 632.04 Press any key to continue . . .

When using a for loop, you should pay attention to the number of items you use. If you use a number n less than the total number of members - 1, only the first n members of the array would be accessed. Here is an example:
using System; public class Exercise { static int Main() { var Numbers = new double[] { 12.44, 525.38, 6.28, 2448.32, 632.04 }; for (var i = 0; i < 3; i++) Console.WriteLine("Number: {0}", Numbers[i]); } } return 0;

This would produce:
Number: 12.44 Number: 525.38 Number: 6.28 Press any key to continue . . .

On the other hand, if you use a number of items higher than the number of members minus one, the compiler would throw an IndexOutOfRangeException exception. Here is an example:
using System; public class Exercise { static int Main() { var Numbers = new double[] { 12.44, 525.38, 6.28, 2448.32, 632.04 }; for (var i = 0; i < 12; i++) Console.WriteLine("Number: {0}", Numbers[i]); } } return 0;

This would produce:

C# 3.0 Practical Learning

516

After the nasty dialog box, you would get:

Therefore, when the number of items is higher than the number of members 1, the compiler may process all members. Then, when it is asked to process members beyond the allowed range, it finds out that there is no other array member. So it gets upset. You could solve the above problem by using exception handling to handle an IndexOutOfRangeException exception. Here is an example:
using System; public class Exercise { static int Main()

C# 3.0 Practical Learning

517

{ }; var Numbers = new double[] { 12.44, 525.38, 6.28, 2448.32, 632.04 try {

} catch (IndexOutOfRangeException) { Console.WriteLine("You tried to access values beyond " + "the allowed range of the members of the array."); } return 0; } }

for (var i = 0; i < 12; i++) Console.WriteLine("Number: {0}", Numbers[i]);

This would produce:
Number: 12.44 Number: 525.38 Number: 6.28 Number: 2448.32 Number: 632.04 You tried to access values beyond the allowed range of the members of the array. Press any key to continue . . .

This solution should not be encouraged. Fortunately, C# and the .NET Framework provide better solutions.

Practical Learning: Using a for Loop
1. To use a for loop, change the Program.cs file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace VideoCollection1 { class Program { static void Main(string[] args) { . . . No Change Console.WriteLine("==============================="); Console.WriteLine("Videos Information"); for (int i = 0; i < 10; i++) { Console.WriteLine("==============================="); Console.WriteLine("Video {0}", i + 1); Console.WriteLine("-------------------------------");

C# 3.0 Practical Learning

518

} } }

} Console.WriteLine("===============================");

Console.WriteLine("Shelf #: Console.WriteLine("Title: Console.WriteLine("Director: Console.WriteLine("Length: Console.WriteLine("Rating: Console.WriteLine("Price:

{0}", ShelfNumbers[i]); {0}", Titles[i]); {0}", Directors[i]); {0} minutes", Lengths[i]); {0}", Ratings[i]); {0}", Prices[i]);

2. Execute the application to see the result:
=============================== Videos Information =============================== Video 1 ------------------------------Shelf #: 2985 Title: The Distinguished Gentleman Director: Jonathan Lynn Length: 112 minutes Rating: R Price: 14.95 =============================== Video 2 ------------------------------Shelf #: 8024 Title: A Perfect Murder Director: Andrew Davis Length: 108 minutes Rating: R Price: 19.95 =============================== Video 3 ------------------------------Shelf #: 5170 Title: Chalte Chalte Director: Aziz Mirza Length: 145 minutes Rating: N/R Price: 22.45 =============================== Video 4 ------------------------------Shelf #: 1304 Title: Ransom Director: Ron Howard Length: 121 minutes Rating: R Price: 14.95 =============================== Video 5 ------------------------------Shelf #: 9187 Title: Not Another Teen Movie Director: Joel Gallen Length: 100 minutes

C# 3.0 Practical Learning

519

Rating: Unrated Price: 9.95 =============================== Video 6 ------------------------------Shelf #: 1193 Title: Madhubaala Director: Shivram Yadav Length: 0 minutes Rating: N/R Price: 17.5 =============================== Video 7 ------------------------------Shelf #: 3082 Title: Get Shorty Director: Barry Sonnenfeld Length: 105 minutes Rating: R Price: 9.95 =============================== Video 8 ------------------------------Shelf #: 8632 Title: Sneakers Director: Paul Alden Robinson Length: 126 minutes Rating: PG-13 Price: 9.95 =============================== Video 9 ------------------------------Shelf #: 4633 Title: Born Invincible Director: Unknown Length: 90 minutes Rating: N/R Price: 5.95 =============================== Video 10 ------------------------------Shelf #: 9623 Title: Hush Director: Jonathan Darby Length: 96 minutes Rating: PG-13 Price: 8.75 =============================== Press any key to continue . . .

For Each Member in the Array
In a for loop, you should know the number of members of the array. If you don't, the C# language allows you to let the compiler use its internal mechanism to get this count and use it to know where to stop counting. To assist you with this, C# provides the foreach operator. To use it, the formula to follow is: C# 3.0 Practical Learning
520

foreach (type identifier in expression) statement

The foreach and the in keywords are required. The first factor of this syntax, type, can be var or the type of the members of the array. It can also be the name of a class as we will learn in Lesson 23. The identifier factor is a name of the variable you will use. The expression factor is the name of the array variable. The statement is what you intend to do with the identifier or as a result of accessing the member of the array. Like a for loop that accesses all members of the array, the foreach operator is used to access each array member, one at a time. Here is an example:
using System; public class Exercise { static int Main() { var Numbers = new double[] { 12.44, 525.38, 6.28, 2448.32, 632.04 }; foreach(var n in Numbers) Console.WriteLine("Number: {0} ", n); return 0; } }

This would produce:
Employees Records Employee Name: Joan Fuller Employee Name: Barbara Boxen Employee Name: Paul Kumar Employee Name: Bertrand Entire

Anonymous Arrays
Introduction
In previous sections, when creating an array, we were specifying its type. As seen in our introduction to variables, a good feature of the var keyword is that, when using it to declare and initialize a variable, you ask the compiler to figure out what type of data the variable is holding. This concept is also valid for an array. An anonymous array is an array variable whose type is left to the compiler to determine, based on the types of values of the array.

Creating an Anonymous Array
C# 3.0 Practical Learning
521

As done for variables so far, when creating an array, you can use the var keyword, initialize the array, but not specify its data type. The formula to use is:
var ArrayName = new[] { Initialization };

The formula is almost similar to that of a normal array, with keywords and operators you are already familiar with. The ArrayName factor is the name of the variable. Notice that the new keyword is directly followed by the square brackets. In the curly brackets, you must initialize the array by providing the necessary values. For the compiler to be able to figure out the type and amount of memory to allocate for the array variable, all values must be of the same type or the same category:

If each value is a number without a decimal part, the compiler checks their range and concludes whether the array needs 32 bits or 64 bits. Here is an example:

using System; using System.Linq; public class Exercise { static int Main() { var Naturals = new[] { 2735, 20, 3647597, 3408, 957 }; var Values = new[] { 0x91FF22, 8168, 0x80080, 0xF822FF, 202684 }; return 0; }

}

If the values are numeric but at least one of them includes a decimal part, the compiler concludes that the array is made of floating-point numbers. If you want to control their precision (float, double, or decimal), add the appropriate suffix to each value. This also means that you can use a combination of natural and decimal numbers, but the presence of at least one number with a decimal part would convert the array into floating point instead of int-based. Here is an example:

using System; using System.Linq; public class Exercise { static int Main() { var Singles = new[] { 1244F, 525.38F, 6.28F, 2448.32F, 632.04F }; var Doubles = new[] { 3.212D, 3047.098D, 732074.02, 18342.3579 }; var Values = new[] { 17.230M, 4808237M, 222.4203M, 948.002009M }; } } return 0;

C# 3.0 Practical Learning

522

If the members are made of true and false values, then compiler will allocate memory for Boolean values for the array. Here is an example:

using System; using System.Linq; public class Exercise { static int Main() { var Qualifications = new[] { true, true, false, true, false }; return 0; }

}

If the members contain values included in single-quotes, the array will be treated as a series of characters. Here is an example:

using System; using System.Linq; public class Exercise { static int Main() { var Categories = new[] { 'C', 'F', 'B', 'C', 'A' }; return 0; }

}

If the values of the members are included in double-quotes, then the array will be considered a group of strings. Here is an example:

using System; using System.Linq; public class Exercise { static int Main() { var Friends = new[] { "Mark", "Frank", "Charlotte", "Jerry" }; return 0; } }

Accessing the Members of an Anonymous Array
After creating an anonymous array, you can access each member using its index. Here is an example that uses a for loop:
using System;

C# 3.0 Practical Learning

523

using System.Linq; public class Exercise { static int Main() { var Friends = new[] { "Mark", "Frank", "Charlotte", "Jerry" }; for (var i = 0; i < 4; i++) Console.WriteLine("Friend: {0}", Friends[i]); } } return 0;

This would produce:
Friend: Mark Friend: Frank Friend: Charlotte Friend: Jerry Press any key to continue . . .

In the same way, you can use a foreach statement to access each member of the array. Here is an example:
using System; using System.Linq; public class Exercise { static int Main() { var Friendlies = new[] { "Mark", "Frank", "Charlotte", "Jerry" }; for (var i = 0; i < 4; i++) Console.WriteLine("Friend: {0}", Friendlies[i]); Console.WriteLine("-----------------------------------"); var Qualifications = new[] { true, true, false, true, false }; foreach (var qualifies in Qualifications) Console.WriteLine("The Member Qualifies: {0}", qualifies); Console.WriteLine("-----------------------------------"); } } return 0;

This would produce:
Friend: Mark Friend: Frank Friend: Charlotte Friend: Jerry ----------------------------------The Member Qualifies: True The Member Qualifies: True The Member Qualifies: False The Member Qualifies: True

C# 3.0 Practical Learning

524

The Member Qualifies: False ----------------------------------Press any key to continue . . .

Selecting a Value From an Array
Introduction
Because an array is a list of items, it could include values that are not useful in all scenarios. For example, having an array made of too many values, at one time you may want to isolate only the first n members of the array, or the last m members of the array, or a range of members from an index i to an index j. Another operation you may be interested to perform is to find out if this or that value exists in the array. One more interesting operation would be to find out what members or how many members of the array respond to this or that criterion. All these operations are useful and possible with different techniques.

Using for and foreach
Consider the following program:
using System; using System.Linq; public class Exercise { static int Main() { var Numbers = new[] { 102, 44, 525, 38, 6, 28, 24481, 327, 632, 104 }; for (var i = 0; i < 10; i++) Console.WriteLine("Number: {0}", Numbers[i]); return 0; } }

This would produce:
Number: 102 Number: 44 Number: 525 Number: 38 Number: 6 Number: 28 Number: 24481 Number: 327 Number: 632 Number: 104 Press any key to continue . . .

C# 3.0 Practical Learning

525

Imagine you want to access only the first n members of the array. To do this, you can use an if conditional statement nested in a for or a foreach loop. Here is an example that produces the first 4 values of the array:
using System; using System.Linq; public class Exercise { static int Main() { var Numbers = new[] { 102, 44, 525, 38, 6, 28, 24481, 327, 632, 104 }; for (var i = 0; i < 10; i++) if (i < 4) Console.WriteLine("Number: {0}", Numbers[i]); } } return 0;

This would produce:
Number: 102 Number: 44 Number: 525 Number: 38 Press any key to continue . . .

You can use the same technique to get the last m members of the array. You can also use a similar technique to get one or a few values inside of the array, based on a condition of your choice. Here is an example that gets the values that are multiple of 5 from the array:
using System; using System.Linq; public class Exercise { static int Main() { var Numbers = new[] { 102, 44, 525, 38, 6, 28, 24481, 327, 632, 104 }; for (var i = 0; i < 10; i++) if (Numbers[i] % 5 == 0) Console.WriteLine("Number: {0}", Numbers[i]); } } return 0;

This would produce:
Number: 525 Press any key to continue . . .

Practical Learning: Checking a Value From an Array
C# 3.0 Practical Learning
526

1. To check a value from an array, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace VideoCollection1 { class Program { static void Main(string[] args) { long[] ShelfNumbers = new long[] { 2985, 8024, 5170, 1304, 9187, 1193, 3082, 8632, 4633, 9623 }; string[] Titles = new string[] { "The Distinguished Gentleman", "A Perfect Murder", "Chalte Chalte", "Ransom", "Not Another Teen Movie", "Madhubaala", "Get Shorty", "Sneakers", "Born Invincible", "Hush" }; string[] Directors = new string[] { "Jonathan Lynn", "Andrew Davis", "Aziz Mirza", "Ron Howard", "Joel Gallen", "Shivram Yadav", "Barry Sonnenfeld", "Paul Alden Robinson", "Unknown", "Jonathan Darby" }; int[] Lengths = new int[] { 112, 108, 145, 121, 100, 0, 105, 126, 90, 96 }; string[] Ratings = new string[] { "R", "R", "N/R", "R", "Unrated", "N/R", "R", "PG-13", "N/R", "PG-13" }; double[] Prices = new double[] { 14.95D, 19.95D, 22.45D, 14.95D, 9.95D, 17.50D, 9.95D, 9.95D, 5.95D, 8.75D }; foreach (int Code in ShelfNumbers) Console.Write("{0}\t", Code); long ShelfNumber = 0; Console.Write("Enter the shelf number of the " + "video you want to check: "); ShelfNumber = long.Parse(Console.ReadLine()); Console.WriteLine(); for (int i = 0; i < 10; i++)

C# 3.0 Practical Learning

527

{ if (ShelfNumbers[i] == ShelfNumber) { Console.WriteLine("==============================="); Console.WriteLine("Video Information"); Console.WriteLine("-------------------------------"); Console.WriteLine("Shelf #: {0}", ShelfNumbers[i]); Console.WriteLine("Title: {0}", Titles[i]); Console.WriteLine("Director: {0}", Directors[i]); Console.WriteLine("Length: {0} minutes", Console.WriteLine("Rating: Console.WriteLine("Price: {0}", Ratings[i]); {0}", Prices[i]);

Lengths[i]);

} } }

} } Console.WriteLine("===============================");

2. Execute the application to test it 3. When prompted, enter a shelf number and press Enter. Here is an example:
2985 8024 5170 1304 9187 1193 3082 8632 9623 Enter the shelf number of the video you want to check: 8632 =============================== Video Information ------------------------------Shelf #: 8632 Title: Sneakers Director: Paul Alden Robinson Length: 126 minutes Rating: PG-13 Price: 9.95 =============================== Press any key to continue . . . 4633

4. Close the DOS window and return to your programming environment

C# 3.0 Practical Learning

528

Arrays and Classes
An Array of a Primitive Type as a Field
Introduction
As we have used them so far, an array is primarily a variable. As such, it can be declared as a member variable of a class. 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:
public class CoordinateSystem { private int[] Points; }

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:
public class CoordinateSystem { private int[] Points = new int[4]; }

You can also allocate memory for an array field in a constructor of the class. Here is an example:
public class CoordinateSystem { private int[] Points; public CoordinateSystem() { Points = new int[4]; } }

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 called before the array can be used. Here is an example: C# 3.0 Practical Learning
529

public class CoordinateSystem { private int[] Points; public CoordinateSystem() { Points = new int[4]; Points[0] Points[1] Points[2] Points[3] = = = = 2; 5; 2; 8;

} }

Practical Learning: Introducing Arrays and Classes
1. Start Microsoft Visual C# and create a Console Application named
RentalProperties1

2. To create a new class, in the Solution Explorer, right-click RenatlProperties1 -> Add -> Class... 3. Set the Name to RentalProperty and press Enter 4. Change the file as follows:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace RentalProperties1 { public enum PropertyType { SingleFamily, Townhouse, Apartment, Unknown }; public class RentalProperty { private long[] PropertyNumbers; private PropertyType[] Types; private short[] Bedrooms; private float[] Bathrooms; private double[] MonthlyRent; public RentalProperty() { PropertyNumbers = new long[] { 192873, 498730, 218502, 612739, 457834, 927439, 570520, 734059 }; Types = new PropertyType[] { PropertyType.SingleFamily, PropertyType.SingleFamily, PropertyType.Apartment, PropertyType.Apartment, PropertyType.Townhouse, PropertyType.Apartment, PropertyType.Apartment, PropertyType.Townhouse };

C# 3.0 Practical Learning

530

Bedrooms = new short[] { 5, 4, 2, 1, 3, 1, 3, 4 }; Bathrooms = new float[] { 3.50F, 2.50F, 1.00F, 1.00F, 2.50F, 1.00F, 2.00F, 1.50F }; MonthlyRent = new double[] { 2250.00D, 1885.00D, 1175.50D, 945.00D, 1750.50D, 1100.00D, 1245.95D, 1950.25D };

} } }

5. Save all and accept the suggested name of the project

Presenting the Array
After an array has been created as 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; public class CoordinateSystem { private int[] Points; public CoordinateSystem() { Points = new int[4]; Points[0] Points[1] Points[2] Points[3] } public void ShowPoints() { Console.WriteLine("Points Coordinates"); Console.WriteLine("P({0}, {1})", Points[0], Points[1]); Console.WriteLine("Q({0}, {1})", Points[2], Points[3]); } } public class Exercise { static int Main() { var Coordinates = new CoordinateSystem(); Coordinates.ShowPoints(); return 0; } } = = = = 2; -5; 2; 8;

This would produce:
Points Coordinates

C# 3.0 Practical Learning

531

P(2, -5) Q(2, 8) Press any key to continue . . .

Practical Learning: Presenting an Array
1. To show the values of the array, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace RentalProperties1 { public enum PropertyType { SingleFamily, Townhouse, Apartment, Unknown }; public class RentalProperty { private long[] PropertyNumbers; private PropertyType[] Types; private short[] Bedrooms; private float[] Bathrooms; private double[] MonthlyRent; public RentalProperty() { PropertyNumbers = new long[] { 192873, 498730, 218502, 612739, 457834, 927439, 570520, 734059 }; Types = new PropertyType[] { PropertyType.SingleFamily, PropertyType.SingleFamily, PropertyType.Apartment, PropertyType.Apartment, PropertyType.Townhouse, PropertyType.Apartment, PropertyType.Apartment, PropertyType.Townhouse }; Bedrooms = new short[] { 5, 4, 2, 1, 3, 1, 3, 4 }; Bathrooms = new float[] { 3.50F, 2.50F, 1.00F, 1.00F, 2.50F, 1.00F, 2.00F, 1.50F }; MonthlyRent = new double[] { 2250.00D, 1885.00D, 1175.50D, 945.00D, 1750.50D, 1100.00D, 1245.95D, 1950.25D };

}

); Rent"); );

public void ShowListing() { Console.WriteLine("Properties Listing"); Console.WriteLine("=============================================" Console.WriteLine("Prop # Property Type Beds Baths Monthly

Console.WriteLine("---------------------------------------------" for (int i = 0; i < 8; i++)

C# 3.0 Practical Learning

532

{ Console.WriteLine("{0}\t{1}\t{2} {3:F}{4,12}", PropertyNumbers[i], Types[i], Bedrooms[i], Bathrooms[i], MonthlyRent[i]);

); } }

} Console.WriteLine("=============================================" }

2. Access the Program.cs file and change it as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace RentalProperties1 { class Program { static void Main(string[] args) { RentalProperty Property = new RentalProperty(); } } } Property.ShowListing();

3. Execute the application to see the result
Properties Listing ============================================= Prop # Property Type Beds Baths Monthly Rent --------------------------------------------192873 SingleFamily 5 3.50 2250 498730 SingleFamily 4 2.50 1885 218502 Apartment 2 1.00 1175.5 612739 Apartment 1 1.00 945 457834 Townhouse 3 2.50 1750.5 927439 Apartment 1 1.00 1100 570520 Apartment 3 2.00 1245.95 734059 Townhouse 4 1.50 1950.25 ============================================= Press any key to continue . . .

4. Close the DOS window and return to your programming environment

Arrays and Methods
Introduction

C# 3.0 Practical Learning

533

Each member of an array holds a legitimate value. Therefore, you can pass a single member of an array as argument. You can pass the name of the array variable with the accompanying index to a method. The main purpose of using an array is to use various values grouped under one name. Still, an array is primarily a variable. As such, it can be passed to a method and it can be returned from a method.

An Array Passed as Argument
Like a regular variable, an array can be passed as argument. To do this, in the parentheses of a method, provide the data type, the empty square brackets, and the name of the argument. Here is an example:
public class CoordinateSystem { public void ShowPoints(int[] Points) { } }

When an array has been passed to a method, it can be used in the body of the method as any array can be, following the rules of array variables. For example, you can display its values. The simplest way you can use an array is to display the values of its members. This could be done as follows:
public class CoordinateSystem { public void ShowPoints(int[] Points) { Console.WriteLine("Points Coordinates"); Console.WriteLine("P({0}, {1})", Points[0], Points[1]); Console.WriteLine("Q({0}, {1})", Points[2], Points[3]); } }

To call a method that takes an array as argument, simply type the name of the array in the parentheses of the called method. Here is an example:
using System; public class CoordinateSystem { public void ShowPoints(int[] Points) { Console.WriteLine("Points Coordinates"); Console.WriteLine("P({0}, {1})", Points[0], Points[1]); Console.WriteLine("Q({0}, {1})", Points[2], Points[3]); } } public class Exercise { static int Main() { var Points = new int[] { -3, 3, 6, 3 }; var Coordinates = new CoordinateSystem();

C# 3.0 Practical Learning

534

} }

Coordinates.ShowPoints(Points); return 0;

This would produce:
Points Coordinates P(-3, 3) Q(6, 3) Press any key to continue . . .

When an array is passed as argument to a method, the array is passed by reference. This means that, if the method makes any change to the array, the change would be kept when the method exits. You can use this characteristic to initialize an array from a method. Here is an example:
using System; public class CoordinateSystem { public void Initialize(int[] Coords) { Coords[0] = -4; Coords[1] = -2; Coords[2] = -6; Coords[3] = 3; } public void ShowPoints(int[] Points) { Console.WriteLine("Points Coordinates"); Console.WriteLine("P({0}, {1})", Points[0], Points[1]); Console.WriteLine("Q({0}, {1})", Points[2], Points[3]); }

}

public class Exercise { static int Main() { var System = new int[4]; var Coordinates = new CoordinateSystem(); Coordinates.Initialize(System); Coordinates.ShowPoints(System); return 0; } }

This would produce:
Points Coordinates P(-4, -2) Q(-6, 3) Press any key to continue . . .

Notice that the CreateNumbers() method receives an un-initialized array but returns it with new values. To enforce the concept of passing a variable by C# 3.0 Practical Learning
535

reference, you can also accompany an array argument with the ref keyword, both when defining the method and when calling it. Here is an example:
using System; public class CoordinateSystem { public void Initialize(ref int[] Coords) { Coords[0] = -4; Coords[1] = -2; Coords[2] = -6; Coords[3] = 3; } public void ShowPoints(int[] Points) { Console.WriteLine("Points Coordinates"); Console.WriteLine("P({0}, {1})", Points[0], Points[1]); Console.WriteLine("Q({0}, {1})", Points[2], Points[3]); } } public class Exercise { static int Main() { var System = new int[4]; var Coordinates = new CoordinateSystem(); Coordinates.Initialize(ref System); Coordinates.ShowPoints(System); } } return 0;

Instead of just one, you can create a method that receive more than one array and you can create a method that receives a combination of one or more arrays and one or more regular arguments. There is no rule that sets some restrictions. You can also create a method that takes one or more arrays as argument(s) and returns a regular value of a primitive type.

Returning an Array From a Method
Like a normal variable, an array can be returned from a method. This means that the method would return a variable that carries various values. When declaring or defining the method, you must specify its data type. When the method ends, it would return an array represented by the name of its variable. You can create a method that takes an array as argument and returns another array as argument.

C# 3.0 Practical Learning

536

To declare a method that returns an array, on the left of the method's name, provide the type of value that the returned array will be made of, followed by empty square brackets. Here is an example:
using System; public class CoordinateSystem { public int[] Initialize() { } }

Remember that a method must always return an appropriate value depending on how it was declared. In this case, if it was specified as returning an array, then make sure it returns an array and not a regular variable. One way you can do this is to declare and possibly initialize a local array variable. After using the local array, you return only its name (without the square brackets). Here is an example:
using System; public class CoordinateSystem { public int[] Initialize() { var Coords = new int[] { 12, 5, -2, -2 }; return Coords; } }

When a method returns an array, that method can be assigned to an array declared locally when you want to use it. Remember to initialize a variable with such a method only if the variable is an array. Here is an example:
using System; public class CoordinateSystem { public int[] Initialize() { var Coords = new int[] { 12, 5, -2, -2 }; } return Coords;

}

public void ShowPoints(int[] Points) { Console.WriteLine("Points Coordinates"); Console.WriteLine("P({0}, {1})", Points[0], Points[1]); Console.WriteLine("Q({0}, {1})", Points[2], Points[3]); }

public class Exercise {

C# 3.0 Practical Learning

537

static int Main() { var System = new int[4]; var Coordinates = new CoordinateSystem(); System = Coordinates.Initialize(); Coordinates.ShowPoints(System); return 0; } }

The method could also be called as follows:
public class Exercise { static int Main() { var Coordinates = new CoordinateSystem(); var System = Coordinates.Initialize(); Coordinates.ShowPoints(System); return 0; } }

If you initialize an array variable with a method that doesn't return an array, you would receive an error.

Main()'s Argument
Introduction
When a program starts, it looks for an entry point. This is the role of the Main() method. In fact, a program, that is an executable program, starts by, and stops with, the Main() method. The way this works is that, at the beginning, the compiler looks for a method called Main. If it doesn't find it, it produces an error. If it finds it, it enters the Main() method 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() method. Consider the following code written in a file saved as Exercise.cs:
using System; public class Exercise { static int Main() {

C# 3.0 Practical Learning

538

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; } }

To execute the application, at the Command Prompt and after Changing to the Directory that contains the file, you would type
csc Exercise.cs

and press Enter. To execute the program, you would type the name Exercise and press Enter. The program would then prompt you for the information it needs.

Command Request from Main()
To compile a program, you would simply type the csc command at the command prompt. Then, to execute a program, you would type its name at the prompt. If you distribute a program, you 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, you can pass a string argument to the Main() method. 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:

C# 3.0 Practical Learning

539

The values the user would provide are stored in a zero-based array without considering the name of the program. The first value (that is, after the name of the program) is stored at index 0, the second at index 1, etc. Based on this, the first argument is represented by args[0], the second is represented by args[1], etc. Each of the values the user types is a string. If any one of them is not a string, you should/must convert/cast its string first to the appropriate value. Consider the following source code:
using System; namespace CSharpLessons { public 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]); 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; } } }

C# 3.0 Practical Learning

540

To compile it at the Command Prompt, after switching to the directory that contains the file, you would type
csc Exercise.cs

and press Enter. To execute the program, you would 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

An Array of Objects
Introduction
As done for primitive types, you can create an array of values where each member of the array is based on a formal class. Of course, you must have a class first. You can use one of the already available classes or you can create your own class. Here is an example:
using System; public enum EmploymentStatus { FullTime, PartTime, Unknown }; public class Employee { private long emplNbr; private string name; private EmploymentStatus st; private double wage; public long EmployeeNumber { get { return emplNbr; } set { emplNbr = value; } } public string EmployeeName { get { return name; } set { name = value; }

C# 3.0 Practical Learning

541

} public EmploymentStatus Status { get { return st; } set { st = value; } } public double HourlySalary { get { return wage; } set { wage = value; } } }

Practical Learning: Introducing Arrays of Objects
1. Create a new Console Application named RentalProperties2 2. To create a new class, in the Solution Explorer, right-click RenatlProperties1 -> Add -> Class... 3. Set the Name to RentalProperty and press Enter 4. Change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace RentalProperties2 { public enum PropertyType { SingleFamily, Townhouse, Apartment, Unknown }; public class RentalProperty { private long nbr; private PropertyType tp; private short bd; private float bt; private double rnt; public RentalProperty() { nbr = 0; tp = PropertyType.Unknown; bd = 0; bt = 0.0F; rnt = 0D; } public RentalProperty(long PropNbr, PropertyType Type, short Beds, float Baths, double Rent)

C# 3.0 Practical Learning

542

{ PropNbr = nbr; Type = PropertyType.Unknown; Beds = bd; Baths = bt; Rent = rnt;

}

public long PropertyNumber { get { return nbr; } set { nbr = value; } } public PropertyType TypeOfProperty { get { return tp; } set { tp = value; } } public short Bedrooms { get { return bd; } set { bd = value; } } public float Bathrooms { get { return bt; } set { bt = value; } } public double MonthlyRent { get { return rnt; } set { rnt = value; } } } }

5. Save all and accept the suggested name of the project

Creating an Array of Objects
To create an array of objects, you can declare an array variable and use the square brackets to specify its size. Here is an example:
public static class Exercise { static void Main(string[] args) { Employee[] StaffMembers = new Employee[3]; } } return 0;

You can also use the var keyword to create the array but omit the first square brackets. Here is an example: 543 C# 3.0 Practical Learning

public static class Exercise { static void Main(string[] args) { var StaffMembers = new Employee[3]; return 0; } }

Initializing an Array of Objects
If you create an array like this, you can then access each member using its index, allocate memory for it using the new operator, then access each of its fields, still using its index, to assign it the desired value. Here is an example:
public static class Exercise { static void Main(string[] args) { var StaffMembers = new Employee[3]; StaffMembers[0] = new Employee(); StaffMembers[0].EmployeeNumber = 20204; StaffMembers[0].EmployeeName = "Harry Fields"; StaffMembers[0].Status = EmploymentStatus.FullTime; StaffMembers[0].HourlySalary = 16.85; StaffMembers[1] = new Employee(); StaffMembers[1].EmployeeNumber = 92857; StaffMembers[1].EmployeeName = "Jennifer Almonds"; StaffMembers[1].Status = EmploymentStatus.FullTime; StaffMembers[1].HourlySalary = 22.25; StaffMembers[2] = new Employee(); StaffMembers[2].EmployeeNumber = 42963; StaffMembers[2].EmployeeName = "Sharon Culbritt"; StaffMembers[2].Status = EmploymentStatus.PartTime; StaffMembers[2].HourlySalary = 10.95; return 0; } }

As an alternative, you can also initialize each member of the array when creating it. To do this, before the semi-colon of creating the array, open the curly brackets, allocate memory for each member and specify the values of each field. To do this, you must use a constructor that takes each member you want to initialize, as argument. Here is an example:
using System; public enum EmploymentStatus { FullTime, PartTime, Unknown };

C# 3.0 Practical Learning

544

public class Employee { private long emplNbr; private string name; private EmploymentStatus st; private double wage; public Employee() { } public Employee(long Number, string Name, EmploymentStatus EStatus, double Salary) { emplNbr = Number; name = Name; st = EStatus; wage = Salary; } public long EmployeeNumber { get { return emplNbr; } set { emplNbr = value; } } public string EmployeeName { get { return name; } set { name = value; } } public EmploymentStatus Status { get { return st; } set { st = value; } } public double HourlySalary { get { return wage; } set { wage = value; } }

}

public static class Exercise { static void Main(string[] args) { var StaffMembers = new Employee[] { new Employee(20204, "Harry Fields", EmploymentStatus.FullTime, 16.85), new Employee(92857, "Jennifer Almonds", EmploymentStatus.FullTime, 22.25), new Employee(42963, "Sharon Culbritt", EmploymentStatus.PartTime, 10.95) };

C# 3.0 Practical Learning

545

return 0; } }

If using the var keyword and a constructor to initialize the array, you can omit calling the name of the class before the square brackets. Here is an example:
public static class Exercise { static void Main(string[] args) { var StaffMembers = new[] { new Employee(20204, "Harry Fields", EmploymentStatus.FullTime, 16.85), new Employee(92857, "Jennifer Almonds", EmploymentStatus.FullTime, 22.25), new Employee(42963, "Sharon Culbritt", EmploymentStatus.PartTime, 10.95) }; return 0; } }

Accessing the Members of the Array
After creating and initializing the array, you can use it as you see fit. For example, you may want to display its values to the user. You can access any member of the array by its index, then use the same index to get its field(s) and consequently its (their) value(s). Here is an example:
public static class Exercise { static void Main(string[] args) { var StaffMembers = new Employee[] { new Employee(20204, "Harry Fields", EmploymentStatus.FullTime, 16.85), new Employee(92857, "Jennifer Almonds", EmploymentStatus.FullTime, 22.25), new Employee(42963, "Sharon Culbritt", EmploymentStatus.PartTime, 10.95) }; Console.WriteLine("Employee Record"); Console.WriteLine("---------------------------"); Console.WriteLine("Employee #: {0}", StaffMembers[2].EmployeeNumber); Console.WriteLine("Full Name: {0}", StaffMembers[2].EmployeeName); Console.WriteLine("Status: {0}", StaffMembers[2].Status); Console.WriteLine("Hourly Wage {0}", StaffMembers[2].HourlySalary); Console.WriteLine("---------------------------\n"); return 0; }

C# 3.0 Practical Learning

546

}

This would produce:
Employee Record --------------------------Employee #: 42963 Full Name: Sharon Culbritt Status: PartTime Hourly Wage 10.95 --------------------------Press any key to continue . . .

Once again, remember that the index you use must be higher than 0 but lower than the number of members - 1. Otherwise, the compiler would throw an IndexOutRangeException exception. In the same way, you can use a for loop to access all members of the array using their index. Here is an example:
public static class Exercise { static void Main(string[] args) { var StaffMembers= new Employee[] { new Employee(20204, "Harry Fields", EmploymentStatus.FullTime, 16.85), new Employee(92857, "Jennifer Almonds", EmploymentStatus.FullTime, 22.25), new Employee(42963, "Sharon Culbritt", EmploymentStatus.PartTime, 10.95) }; Console.WriteLine("Employees Records"); Console.WriteLine("=========================="); for (int i = 0; i < 3; i++) { Console.WriteLine("Employee #: {0}", StaffMembers[i].EmployeeNumber); Console.WriteLine("Full Name: {0}", StaffMembers[i].EmployeeName); Console.WriteLine("Status: {0}", StaffMembers[i].Status); Console.WriteLine("Hourly Wage {0}", StaffMembers[i].HourlySalary); Console.WriteLine("---------------------------"); } return 0; } }

To access each member of the array, you can use the foreach operator that allows you to use a name for each member and omit the square brackets. Here is an example:
public static class Exercise { static void Main(string[] args)

C# 3.0 Practical Learning

547

{ var StaffMembers = new Employee[] { new Employee(20204, "Harry Fields", EmploymentStatus.FullTime, 16.85), new Employee(92857, "Jennifer Almonds", EmploymentStatus.FullTime, 22.25), new Employee(42963, "Sharon Culbritt", EmploymentStatus.PartTime, 10.95) }; Console.WriteLine("Employees Records"); Console.WriteLine("=========================="); foreach(var Member in StaffMembers) { Console.WriteLine("Employee #: {0}", Member.EmployeeNumber); Console.WriteLine("Full Name: {0}", Member.EmployeeName); Console.WriteLine("Status: {0}", Member.Status); Console.WriteLine("Hourly Wage {0}", Member.HourlySalary); Console.WriteLine("---------------------------"); } return 0; } }

This would produce:
Employees Records ========================== Employee #: 20204 Full Name: Harry Fields Status: FullTime Hourly Wage 16.85 --------------------------Employee #: 92857 Full Name: Jennifer Almonds Status: FullTime Hourly Wage 22.25 --------------------------Employee #: 42963 Full Name: Sharon Culbritt Status: PartTime Hourly Wage 10.95 --------------------------Press any key to continue . . .

Practical Learning: Using an Array of Objects
1. Access the Program.cs file and change it file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace RentalProperties2 {

C# 3.0 Practical Learning

548

public class Program { static void Main(string[] args) { RentalProperty[] Properties = new RentalProperty[8]; Properties[0] = new RentalProperty(); Properties[0].PropertyNumber = 192873; Properties[0].TypeOfProperty = PropertyType.SingleFamily; Properties[0].Bedrooms = 5; Properties[0].Bathrooms = 3.50F; Properties[0].MonthlyRent = 2250.00D; Properties[1] = new RentalProperty(); Properties[1].PropertyNumber = 498730; Properties[1].TypeOfProperty = PropertyType.SingleFamily; Properties[1].Bedrooms = 4; Properties[1].Bathrooms = 2.50F; Properties[1].MonthlyRent = 1885.00D; Properties[2] = new RentalProperty(); Properties[2].PropertyNumber = 218502; Properties[2].TypeOfProperty = PropertyType.Apartment; Properties[2].Bedrooms = 2; Properties[2].Bathrooms = 1.00F; Properties[2].MonthlyRent = 1175.50D; Properties[3] = new RentalProperty(); Properties[3].PropertyNumber = 612739; Properties[3].TypeOfProperty = PropertyType.Apartment; Properties[3].Bedrooms = 1; Properties[3].Bathrooms = 1.00F; Properties[3].MonthlyRent = 945.00D; Properties[4] = new RentalProperty(); Properties[4].PropertyNumber = 457834; Properties[4].TypeOfProperty = PropertyType.Townhouse; Properties[4].Bedrooms = 3; Properties[4].Bathrooms = 2.50F; Properties[4].MonthlyRent = 1750.50D; Properties[5] = new RentalProperty(); Properties[5].PropertyNumber = 927439; Properties[5].TypeOfProperty = PropertyType.Apartment; Properties[5].Bedrooms = 1; Properties[5].Bathrooms = 1.00F; Properties[5].MonthlyRent = 1100.00D; Properties[6] = new RentalProperty(); Properties[6].PropertyNumber = 570520; Properties[6].TypeOfProperty = PropertyType.Apartment; Properties[6].Bedrooms = 3; Properties[6].Bathrooms = 2.00F; Properties[6].MonthlyRent = 1245.95D; Properties[7] = new RentalProperty(); Properties[7].PropertyNumber = 734059; Properties[7].TypeOfProperty = PropertyType.Townhouse; Properties[7].Bedrooms = 4; Properties[7].Bathrooms = 1.50F; Properties[7].MonthlyRent = 1950.25D; Console.WriteLine("Properties Listing"); Console.WriteLine("=============================================" ); Rent"); Console.WriteLine("Prop # Property Type Beds Baths Monthly 549

C# 3.0 Practical Learning

Console.WriteLine("---------------------------------------------" ); for (int i = 0; i < 8; i++) { Console.WriteLine("{0}\t{1}\t{2} {3:F}{4,12}", Properties[i].PropertyNumber, Properties[i].TypeOfProperty, Properties[i].Bedrooms, Properties[i].Bathrooms, Properties[i].MonthlyRent); } Console.WriteLine("=============================================" } } }

);

2. Execute the application to see the result
Properties Listing ============================================= Prop # Property Type Beds Baths Monthly Rent --------------------------------------------192873 SingleFamily 5 3.50 2250 498730 SingleFamily 4 2.50 1885 218502 Apartment 2 1.00 1175.5 612739 Apartment 1 1.00 945 457834 Townhouse 3 2.50 1750.5 927439 Apartment 1 1.00 1100 570520 Apartment 3 2.00 1245.95 734059 Townhouse 4 1.50 1950.25 ============================================= Press any key to continue . . .

3. Close the DOS window and return to your programming environment

A Class Array as a Field
Introduction
Like a primitive type, an array of objects can be made a field of a class. You can primarily declare the array and specify its size. Here is an example:
public class CompanyRecords { Employee[] Employees = new Employee[2]; }

After doing this, you can then initialize the array from the index of each member. Alternatively, as we saw for field arrays of primitive types, you can declare the array in the body of the class, then use a constructor or another method of the class to allocate memory for it. To initialize the array, remember that each member is a value that must be allocated on the heap. Therefore, apply the new operator on each member of the array to allocate its memory, and then initialize it. Here is an example: 550 C# 3.0 Practical Learning

public class CompanyRecords { Employee[] Employees; public CompanyRecords() { Employees = new Employee[2]; Employees[0] = new Employee(); Employees[0].EmployeeNumber = 70128; Employees[0].EmployeeName = "Frank Dennison"; Employees[0].Status = EmploymentStatus.PartTime; Employees[0].HourlySalary = 8.65; Employees[1] = new Employee(); Employees[1].EmployeeNumber = 24835; Employees[1].EmployeeName = "Jeffrey Arndt"; Employees[1].Status = EmploymentStatus.Unknown; Employees[1].HourlySalary = 16.05; } }

If the class used as field has an appropriate constructor, you can use it to initialize each member of the array. Here is an example:
public class CompanyRecords { Employee[] Employees; public CompanyRecords() { Employees = new Employee[] { new Employee(70128, "Justine Hearson", EmploymentStatus.PartTime, 10.62), new Employee(24835, "Bertha Hack", EmploymentStatus.FullTime, 18.94), new Employee(70128, "Frank Dennison", EmploymentStatus.Seasonal, 12.48), new Employee(24835, "Jeffrey Arndt", EmploymentStatus.PartTime, 16.05), }; } }

Using the Array
Once you have created and initialized the array, you can use it as you see fit, such as displaying its values to the user. You must be able to access each member of the array, using its index. Once you have accessed member, you can get to its fields or properties. Here is an example:
using System; public enum EmploymentStatus { FullTime, PartTime, Seasonal,

C# 3.0 Practical Learning

551

Unknown }; public class Employee { private long emplNbr; private string name; private EmploymentStatus st; private double wage; public Employee() { } public Employee(long Number, string Name, EmploymentStatus EStatus, double Salary) { emplNbr = Number; name = Name; st = EStatus; wage = Salary; } public long EmployeeNumber { get { return emplNbr; } set { emplNbr = value; } } public string EmployeeName { get { return name; } set { name = value; } } public EmploymentStatus Status { get { return st; } set { st = value; } } public double HourlySalary { get { return wage; } set { wage = value; } }

}

public class CompanyRecords { Employee[] Employees; public CompanyRecords() { Employees = new Employee[] { new Employee(70128, "Justine Hearson", EmploymentStatus.PartTime, 10.62), new Employee(24835, "Bertha Hack", EmploymentStatus.FullTime, 18.94),

C# 3.0 Practical Learning

552

}; }

new Employee(70128, "Frank Dennison", EmploymentStatus.Seasonal, 12.48), new Employee(24835, "Jeffrey Arndt", EmploymentStatus.PartTime, 16.05),

public void ShowRecords() { Console.WriteLine("Employees Records"); Console.WriteLine("=========================="); foreach (var Member in Employees) { Console.WriteLine("Employee #: {0}", Member.EmployeeNumber); Console.WriteLine("Full Name: {0}", Member.EmployeeName); Console.WriteLine("Status: {0}", Member.Status); Console.WriteLine("Hourly Wage {0}", Member.HourlySalary); Console.WriteLine("---------------------------"); }

} }

public static class Exercise { static void Main(string[] args) { var Records = new CompanyRecords(); Records.ShowRecords(); return 0; } }

This would produce:
Employees Records ========================== Employee #: 70128 Full Name: Justine Hearson Status: PartTime Hourly Wage 10.62 --------------------------Employee #: 24835 Full Name: Bertha Hack Status: FullTime Hourly Wage 18.94 --------------------------Employee #: 70128 Full Name: Frank Dennison Status: Seasonal Hourly Wage 12.48 --------------------------Employee #: 24835 Full Name: Jeffrey Arndt Status: PartTime Hourly Wage 16.05 --------------------------Press any key to continue . . .

C# 3.0 Practical Learning

553

Arrays of Objects and Methods
Passing an Array of Objects as Argument
As done for an array of a primitive type, you can pass an array of objects as arguments. You follow the same rules we reviewed; that is, in the parentheses of a method, enter the class name, the empty square brackets, and the name of the argument. Here is an example:
public class CompanyRecords { public CompanyRecords(Employee[] Employees) { } }

You can then access each member of the argument and do what you judge necessary. For example, you can display the values that the argument is holding. To call a method that takes an array of objects, in its parentheses, just enter the name of the array. Here is an example:
public class CompanyRecords { public CompanyRecords(Employee[] Employees) { Employees = new Employee[] { new Employee(70128, "Justine Hearson", EmploymentStatus.PartTime, 10.62), new Employee(24835, "Bertha Hack", EmploymentStatus.FullTime, 18.94), new Employee(70128, "Frank Dennison", EmploymentStatus.Seasonal, 12.48), new Employee(24835, "Jeffrey Arndt", EmploymentStatus.PartTime, 16.05), }; } } public static class Exercise { static void Main(string[] args) { var Values = new Employee[4]; CompanyRecords Records = new CompanyRecords(Values); Records.ShowRecords(); } } return 0;

As stated for an array of primitive type, an array of objects passed as argument is treated as a reference. You can use this characteristic of arrays C# 3.0 Practical Learning
554

to initialize the array. You can also indicate that the array is passed by reference by preceding its name with the ref keyword.

Returning an Array of Objects
An array of objects can be returned from a method. To indicate this when defining the method, first type the name of the class followed by square brackets. Here is an example:
public class CompanyRecords { public Employee[] RegisterEmployees() { } }

In the body of the method, you can take care of any assignment you want. The major rule to follow is that, before exiting the method, you must return an array of the class indicated on the left side of the method name. To use the method, you can simply call. If you want, since the method returns an array, you can retrieve that series and store it in a local array value for later use. Here is an example:
using System; public enum EmploymentStatus { FullTime, PartTime, Seasonal, Unknown }; public class Employee { private long emplNbr; private string name; private EmploymentStatus st; private double wage; public Employee() { } public Employee(long Number, string Name, EmploymentStatus EStatus, double Salary) { emplNbr = Number; name = Name; st = EStatus; wage = Salary; } public long EmployeeNumber { get { return emplNbr; } set { emplNbr = value; }

C# 3.0 Practical Learning

555

} public string EmployeeName { get { return name; } set { name = value; } } public EmploymentStatus Status { get { return st; } set { st = value; } } public double HourlySalary { get { return wage; } set { wage = value; } } } public class CompanyRecords { public CompanyRecords() { } public Employee[] RegisterEmployees() { var Employees = new Employee[] { new Employee(70128, "Justine Hearson", EmploymentStatus.PartTime, 10.62), new Employee(24835, "Bertha Hack", EmploymentStatus.FullTime, 18.94), new Employee(70128, "Frank Dennison", EmploymentStatus.Seasonal, 12.48), new Employee(24835, "Jeffrey Arndt", EmploymentStatus.PartTime, 16.05), }; return Employees; } public void ShowRecords(ref Employee[] Records) { Console.WriteLine("Employees Records"); Console.WriteLine("=========================="); foreach (var Staff in Records) { Console.WriteLine("Employee #: {0}", Staff.EmployeeNumber); Console.WriteLine("Full Name: {0}", Staff.EmployeeName); Console.WriteLine("Status: {0}", Staff.Status); Console.WriteLine("Hourly Wage {0}", Staff.HourlySalary); Console.WriteLine("---------------------------"); }

} }

public static class Exercise

C# 3.0 Practical Learning

556

{ static void Main(string[] args) { var Records = new CompanyRecords(); var Contractors = Records.RegisterEmployees(); Records.ShowRecords(ref Contractors); return 0; } }

Practical Learning: Using Array of Objects With Methods
1. To apply what we learned in the last few sections, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace RentalProperties2 { public class Program { private static void ShowProperties(RentalProperty[] Properties) { Console.WriteLine("Properties Listing"); Console.WriteLine("========================================== ==="); Console.WriteLine("Prop # Property Type Beds Baths Monthly Rent"); Console.WriteLine("--------------------------------------------"); for (int i = 0; i < 8; i++) { Console.WriteLine("{0}\t{1}\t{2} {3:F}{4,12}", Properties[i].PropertyNumber, Properties[i].TypeOfProperty, Properties[i].Bedrooms, Properties[i].Bathrooms, Properties[i].MonthlyRent); } Console.WriteLine("========================================== ==="); } private static RentalProperty[] CreateListing() { RentalProperty[] HousesToRent = new RentalProperty[8]; HousesToRent[0] = new RentalProperty(); HousesToRent[0].PropertyNumber = 192873; HousesToRent[0].TypeOfProperty = PropertyType.SingleFamily; HousesToRent[0].Bedrooms = 5; HousesToRent[0].Bathrooms = 3.50F; HousesToRent[0].MonthlyRent = 2250.00D; 557 C# 3.0 Practical Learning

HousesToRent[1] = new RentalProperty(); HousesToRent[1].PropertyNumber = 498730; HousesToRent[1].TypeOfProperty = PropertyType.SingleFamily; HousesToRent[1].Bedrooms = 4; HousesToRent[1].Bathrooms = 2.50F; HousesToRent[1].MonthlyRent = 1885.00D; HousesToRent[2] = new RentalProperty(); HousesToRent[2].PropertyNumber = 218502; HousesToRent[2].TypeOfProperty = PropertyType.Apartment; HousesToRent[2].Bedrooms = 2; HousesToRent[2].Bathrooms = 1.00F; HousesToRent[2].MonthlyRent = 1175.50D; HousesToRent[3] = new RentalProperty(); HousesToRent[3].PropertyNumber = 612739; HousesToRent[3].TypeOfProperty = PropertyType.Apartment; HousesToRent[3].Bedrooms = 1; HousesToRent[3].Bathrooms = 1.00F; HousesToRent[3].MonthlyRent = 945.00D; HousesToRent[4] = new RentalProperty(); HousesToRent[4].PropertyNumber = 457834; HousesToRent[4].TypeOfProperty = PropertyType.Townhouse; HousesToRent[4].Bedrooms = 3; HousesToRent[4].Bathrooms = 2.50F; HousesToRent[4].MonthlyRent = 1750.50D; HousesToRent[5] = new RentalProperty(); HousesToRent[5].PropertyNumber = 927439; HousesToRent[5].TypeOfProperty = PropertyType.Apartment; HousesToRent[5].Bedrooms = 1; HousesToRent[5].Bathrooms = 1.00F; HousesToRent[5].MonthlyRent = 1100.00D; HousesToRent[6] = new RentalProperty(); HousesToRent[6].PropertyNumber = 570520; HousesToRent[6].TypeOfProperty = PropertyType.Apartment; HousesToRent[6].Bedrooms = 3; HousesToRent[6].Bathrooms = 2.00F; HousesToRent[6].MonthlyRent = 1245.95D; HousesToRent[7] = new RentalProperty(); HousesToRent[7].PropertyNumber = 734059; HousesToRent[7].TypeOfProperty = PropertyType.Townhouse; HousesToRent[7].Bedrooms = 4; HousesToRent[7].Bathrooms = 1.50F; HousesToRent[7].MonthlyRent = 1950.25D; } return HousesToRent;

static void Main(string[] args) { RentalProperty[] Properties = CreateListing(); ShowProperties(Properties); } } }

2. Execute the application to see the result 3. Close the DOS window and return to your programming environment

C# 3.0 Practical Learning

558

Arrays and Delegates
Introduction
While a regular method can be used to return an array, you can use the features of a delegate to return an array of methods or to take an array of methods as arguments. Of course before proceeding, you must first create the necessary delegate. Here is an example:
using System; delegate double Measure(double R); public static class Program { static int Main(string[] args) { return 0; } }

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), if any. Here are examples of such functions:
using System; delegate double Measure(double R); public class Circle { const double PI = 3.14159; double Diameter(double Radius) { return Radius * 2; } double Circumference(double Radius) { return Diameter(Radius) * PI; } double Area(double Radius) { return Radius * Radius * PI; }

}

public static class Program { static void Main(string[] args) return 0; }

{

C# 3.0 Practical Learning

559

}

An Array of Delegates
To create an array of delegates, declare a normal array as we have done so far. 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); public class Circle { const double PI = 3.14159; public double Diameter(double Radius) { return Radius * 2; } public double Circumference(double Radius) { return Diameter(Radius) * PI; } public double Area(double Radius) { return Radius * Radius * PI; }

}

public static class Program { static void Main(string[] args) { double R = 12.55; Circle circ = new Circle(); Measure[] Calc = new Measure[3]; Calc[0] = new Measure(circ.Diameter); double D = Calc[0](R); Calc[1] = new Measure(circ.Circumference); double C = Calc[1](R); Calc[2] = new Measure(circ.Area); double A = Calc[2](R); Console.WriteLine("Circle Characteristics"); Console.WriteLine("Diameter: {0}", D); Console.WriteLine("Circumference: {0}", C); Console.WriteLine("Area: {0}\n", A); } } return 0;

You can also list the members of the array when creating it. After creating the array, you can retrieve its value and store it in a variable. Here is an example:
public static class Program

C# 3.0 Practical Learning

560

{ static void Main(string[] args) { double R = 12.55; Circle circ = new Circle(); Measure[] Calc = new Measure[] { new Measure(circ.Diameter), new Measure(circ.Circumference), new Measure(circ.Area) }; double D = Calc[0](R); double C = Calc[1](R); double A = Calc[2](R); Console.WriteLine("Circle Characteristics"); Console.WriteLine("Diameter: {0}", D); Console.WriteLine("Circumference: {0}", C); Console.WriteLine("Area: {0}\n", A); return 0; } }

The above code could also be written as follows:
public static class Program { static void Main(string[] args) { double R = 12.55; Circle circ = new Circle(); Measure[] Calc = new Measure[] { new Measure(circ.Diameter), new Measure(circ.Circumference), new Measure(circ.Area) }; Console.WriteLine("Circle Characteristics"); Console.WriteLine("Diameter: {0}", Calc[0](R)); Console.WriteLine("Circumference: {0}", Calc[1](R)); Console.WriteLine("Area: {0}\n", Calc[2](R)); } } return 0;

This would produce:
Circle Characteristics Diameter: 25.1 Circumference: 78.8539 Area: 494.808

C# 3.0 Practical Learning

561

Multidimensional Arrays
Fundamentals of Multidimensional Arrays
Introduction
The arrays we used so far were made of a uniform series, where all members consisted of a simple list, like a column of names on a piece of paper. Also, all items fit in one list. This type of array is referred to as onedimensional. 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 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 multidimensional array is a series of arrays so that each arrays contains its own sub-array(s).

Practical Learning: Introducing Multidimensional Arrays
1. Create a new Console Application named DepartmentStore3 2. Change the Program.cs file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore3 { public class Program { static void Main(string[] args) { long ItemID = 0; string Description = "Unknown"; double Price = 0.00D; Console.WriteLine("Receipt"); Console.WriteLine("Item Number: {0}", ItemID); Console.WriteLine("Description: {0}", Description); Console.WriteLine("Unit Price: {0:C}\n", Price);

C# 3.0 Practical Learning

562

} } }

3. Execute the application to see the result. This would produce:
Receipt Item Number: 0 Description: Unknown Unit Price: $0.00 Press any key to continue . . .

4. Close the DOS window

Creating a Two-Dimensional Array
The most basic multidimensional array is made of two dimensions. This is referred to as two-dimensional. To create a two-dimensional array, declare the array variable as we have done so far 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 various ways you can initialize a two-dimensional 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];

Or you can use the var keyword:
var VariableName = new DataType[Number1,Number2];

Either way, in the right pair of square brackets, enter two integers separated by a comma. Here is an example:
using System; public static class Exercise { public static int Main(string[] args) { var Members = new string[2, 4]; } } return 0;

In our declaration, the Members variable contains two lists. Each of the two lists contains 4 elements. This means that the first list contains 4 elements and the second list contains 4 elements. Therefore, the whole list is made of 8 elements (2 * 4 = 8). Because the variable is declared as a string, each of the 8 items must be a string. You can also create a two-dimensional array that takes more than two lists, such as 3, 4, 5 or more. Here is an example: C# 3.0 Practical Learning
563

using System; public static class Exercise { public static int Main(string[] args) { var Prices = new double[5, 8]; return 0; } }

This time, the variable has 5 lists and each list contains 8 elements. This means that the whole variable contains 5 * 8 = 40 elements. If you want to declare the array variable using the first formula where you don't know the sizes of the lists, you must use the data type of the array and you can omit the right square brackets. Here is an example:
using System; public static class Exercise { public static int Main(string[] args) { string[,] Members; } } return 0;

In this case also, remember that you need the square brackets. If you use the var keyword, you don't need the left square brackets but, in the right square brackets, you must specify the sizes. 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; public static class Exercise { public static int Main(string[] args) { var Members = new string[2, 4] { {"Celeste", "Mathurin", "Alex", "Germain"}, // First List {"Jeremy", "Mathew", "Anselme", "Frederique"} // Second List }; } } return 0;

C# 3.0 Practical Learning

564

When initializing a two-dimensional array, remember the dimensions. The number on the left side of the right comma specifies the number of main lists and the number on the right side of the right comma specifies the number of elements in each list. Here is an example:
using System; public static class Exercise { public static int Main(string[] args) { var Prices = new double[5, 8] { { 10.50, 2.35, 49.75, 202.35, 8.70, 58.20, 34.85, 48.50 }, { 23.45, 878.50, 26.35, 475.90, 2783.45, 9.50, 85.85, 792.75 }, { 47.95, 72.80, 34.95, 752.30, 49.85, 938.70, 45.05, 9.80 }, { 759.25, 73.45, 284.35, 70.95, 82.05, 34.85, 102.30, 84.50 }, { 29.75, 953.45, 79.55, 273.45, 975.90, 224.75, 108.25, 34.05 } }; return 0; } }

If you use this technique to initialize an array, you can omit specifying the dimension of the array. That is, you can remove the numbers in the right square brackets. Here is an example:
using System; public static class Exercise { static int Main(string[] args) { var Members = new string[,] { {"Celeste", "Mathurin", "Alex", "Germain"}, // First List {"Jeremy", "Mathew", "Anselme", "Frederique"} // Second List }; } } return 0;

Practical Learning: Creating a Two-Dimensional Array
1. To create and use a two-dimensional array, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

C# 3.0 Practical Learning

565

namespace DepartmentStore3 { public class Program { static void Main(string[] args) { long ItemID = 0; string Description = "Unknown"; double Price = 0.00D; // 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 }; { }; } ", ", "

double[,] UnitPrice = new double[2, 5] { 275.25D, 180.05D, 50.00D, 265.35D, 245.55D }, { 45.55D, 25.65D, 28.25D, 48.55D, 19.95D }

} } }

Console.WriteLine("Receipt"); Console.WriteLine("Item Number: {0}", ItemID); Console.WriteLine("Description: {0}", Description); Console.WriteLine("Unit Price: {0:C}\n", Price);

2. Save the file

Accessing the Members of a Two-Dimensional Array

C# 3.0 Practical Learning

566

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. If you create an array without initializing using the curly brackets, you can use this technique of accessing the members by the square brackets to initialize each member of the array. Here is an example:
using System; public static class Exercise { static int Main(string[] args) { var Members = new string[2,4]; Members[0, Members[0, Members[0, Members[0, Members[1, Members[1, Members[1, Members[1, } } return 0; 0] 1] 2] 3] 0] 1] 2] 3] = = = = = = = = "Celeste"; "Mathurin"; "Alex"; "Germain"; "Jeremy"; "Mathew"; "Anselme"; "Frederique"; // // // // // // // // Member Member Member Member Member Member Member Member of of of of of of of of the the the the the the the the First List First List First List First List Second List Second List Second List Second List

You can use this same technique to retrieve the value of each member of the array. Here is an example:
using System; public static class Exercise { static int Main(string[] args) { var Members = new string[2,4]; Members[0, Members[0, Members[0, Members[0, Members[1, Members[1, Members[1, Members[1, 0] 1] 2] 3] 0] 1] 2] 3] = = = = = = = = "Celeste"; "Mathurin"; "Alex"; "Germain"; "Jeremy"; "Mathew"; "Anselme"; "Frederique"; // // // // // // // // 0]); 1]); 2]); 3]); 0]); 1]); 567 Member Member Member Member Member Member Member Member of of of of of of of of the the the the the the the the First List First List First List First List Second List Second List Second List Second List

Console.WriteLine(Members[0, Console.WriteLine(Members[0, Console.WriteLine(Members[0, Console.WriteLine(Members[0, Console.WriteLine(Members[1, Console.WriteLine(Members[1,

C# 3.0 Practical Learning

Console.WriteLine(Members[1, 2]); Console.WriteLine(Members[1, 3]); } } return 0;

This would produce:
Celeste Mathurin Alex Germain Jeremy Mathew Anselme Frederique Press any key to continue . . .

As we described it earlier, a two-dimensional array is list of two array, or two arrays of arrays. In order words, the second arrays are nested in the first arrays. In the same way, if you want to access them using a loop, you can nest one for loop inside of a first for loop. The external loop accesses a member of the main array and the second loop accesses the internal list of the current array. Here is an example:
using System; public static class Exercise { static int Main(string[] args) { var Members = new string[2,4]; Members[0, Members[0, Members[0, Members[0, Members[1, Members[1, Members[1, Members[1, 0] 1] 2] 3] 0] 1] 2] 3] = = = = = = = = "Celeste"; "Mathurin"; "Alex"; "Germain"; "Jeremy"; "Mathew"; "Anselme"; "Frederique"; // // // // // // // // Member Member Member Member Member Member Member Member of of of of of of of of the the the the the the the the First List First List First List First List Second List Second List Second List Second List

for (int External = 0; External < 2; External++) for (int Internal = 0; Internal < 4; Internal++) Console.WriteLine(Members[External, Internal]); } } return 0;

To apply a foreach operator, access only each member of the internal list. Here is an example:
using System; public static class Exercise { static int Main(string[] args) {

C# 3.0 Practical Learning

568

var Members = new string[2, 4]; Members[0, Members[0, Members[0, Members[0, Members[1, Members[1, Members[1, Members[1, 0] 1] 2] 3] 0] 1] 2] 3] = = = = = = = = "Celeste"; "Mathurin"; "Alex"; "Germain"; "Jeremy"; "Mathew"; "Anselme"; "Frederique"; // // // // // // // // Member Member Member Member Member Member Member Member of of of of of of of of the the the the the the the the First List First List First List First List Second List Second List Second List Second List

foreach (var Internal in Members) Console.WriteLine(Internal); return 0; } }

Practical Learning: Accessing the Members
1. To retrieve the values of a two-dimensional array, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore3 { public class Program { static void Main(string[] args) { long ItemID = 0; string Description = "Unknown"; double Price = 0.00D; // 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",

", 569

C# 3.0 Practical Learning

} };

"Baby three-piece Set "Girls Jeans with Heart Belt

", "

double[,] UnitPrice = new double[2, 5] { { 275.25D, 180.05D, 50.00D, 265.35D, 245.55D }, { 45.55D, 25.65D, 28.25D, 48.55D, 19.95D } }; // 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"); Console.WriteLine("Item Number: {0}", ItemID); Console.WriteLine("Description: {0}", Description); Console.WriteLine("Unit Price: {0:C}\n", Price); } } }

2. Execute the application and test it. Here is an example:
Enter Item Number: 739579 Receipt Item Number: 739579 Description: Men Cotton Polo Shirt Unit Price: $45.55 Press any key to continue . . .

3. Close the DOS window 4. Execute the application again and enter a different item number. Here is an example:

C# 3.0 Practical Learning

570

Enter Item Number: 273644 Receipt Item Number: 273644 Description: Unknown Unit Price: $0.00 Press any key to continue . . .

5. Close the DOS window

Multidimensional Arrays
Introduction
Beyond two dimensions, you can create an array variable that represents various lists, and each list contains various internal lists, and each internal list contains its own elements. This is referred to as a multidimensional array. One of the rules you must follow is that, as always, all members of the array must be of the same type.

Creating a Multidimensional Array
To create a multidimensional array, add as many commas in the square brackets as you judge them necessary. If you only want to declare the variable without indicating the actual number of lists, you can specify the data type followed by square brackets and the commas. Here is an example that represents a three-dimensional array that is not initialized:
using System; public static class Exercise { static int Main(string[] args) { double[,,] Number; } } return 0;

If you know the types of members the array will use, you can use the assignment operator and specify the numbers of lists in the square brackets. Here is an example:
using System; public static class Exercise { static int Main(string[] args) { double[,,] Number = new double[2, 3, 5]; return 0; } }

C# 3.0 Practical Learning

571

In this case, you can use the var keyword on the left side of the name of the variable:
using System; public static class Exercise { static int Main(string[] args) { var Number = new double[2, 3, 5]; } } return 0;

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. As a result, the array contains 2 * 3 * 5 = 30 members.

Initializing a Multidimensional Array
As always, there are various ways you can initialize an array. To initialize a multidimensional array when creating it, you use an opening and a closing curly brackets for each list but they must be nested. The most external pair of curly brackets represents the main array. Inside of the main curly brackets, the first nested curly brackets represent a list of the first dimension. Inside of those brackets, you use another set curly brackets to represent a list that would be nested. You continue this up to the most internal array. Then, in that last set, you initialize the members of the array by specifying their values. Here is an example:
using System; public static class Exercise { static int Main(string[] args) { var Number = new double[2, 3, 5] { { { 12.44, 525.38, -6.28, 2448.32, 632.04 }, {-378.05, 48.14, 634.18, 762.48, 83.02 }, { 64.92, -7.44, 86.74, -534.60, 386.73 } }, { { 48.02, 120.44, 38.62, 526.82, 1704.62 }, { 56.85, 105.48, 363.31, 172.62, 128.48 }, { 906.68, 47.12, -166.07, 4444.26, 408.62 } }, }; return 0; } }

Access to Members of a Multidimensional Array
C# 3.0 Practical Learning
572

To access a 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. You can use this technique to initialize the array if you had only created it. Here is an example:
using System; public static class Exercise { static int Main(string[] args) { var Number = new double[2, 3, 5]; Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, } } return 0; 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0] 1] 2] 3] 4] 0] 1] 2] 3] 4] 0] 1] 2] 3] 4] 0] 1] 2] 3] 4] 0] 1] 2] 3] 4] 0] 1] 2] 3] 4] = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 12.44; 525.38; -6.28; 2448.32; 632.04; -378.05; 48.14; 634.18; 762.48; 83.02; 64.92; -7.44; 86.74; -534.60; 386.73; 48.02; 120.44; 38.62; 526.82; 1704.62; 56.85; 105.48; 363.31; 172.62; 128.48; 906.68; 47.12; -166.07; 4444.26; 408.62;

This is the same approach you can use to access each member of the array to check or retrieve its value. Here are examples:
using System; public static class Exercise { static int Main(string[] args) { double[, ,] number = new double[2, 3, 5]

C# 3.0 Practical Learning

573

{ { { 12.44, 525.38, -6.28, 2448.32, 632.04 }, {-378.05, 48.14, 634.18, 762.48, 83.02 }, { 64.92, -7.44, 86.74, -534.60, 386.73 } { 48.02, 120.44, 38.62, 526.82,1704.62 }, 56.85, 105.48, 363.31, 172.62, 128.48 }, { 906.68, 47.12,-166.07, 4444.26, 408.62 }

}, { { }, }; 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] Console.WriteLine("Number[0][1][0] Console.WriteLine("Number[0][1][1] Console.WriteLine("Number[0][1][2] Console.WriteLine("Number[0][1][3] Console.WriteLine("Number[0][1][4] Console.WriteLine("Number[0][2][0] Console.WriteLine("Number[0][2][1] Console.WriteLine("Number[0][2][2] Console.WriteLine("Number[0][2][3] Console.WriteLine("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] Console.WriteLine("Number[1][1][0] Console.WriteLine("Number[1][1][1] Console.WriteLine("Number[1][1][2] Console.WriteLine("Number[1][1][3] Console.WriteLine("Number[1][1][4] Console.WriteLine("Number[1][2][0] Console.WriteLine("Number[1][2][1] Console.WriteLine("Number[1][2][2] Console.WriteLine("Number[1][2][3] Console.WriteLine("Number[1][2][4] } } return 0; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = {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]); {0}", number[0, 1, 0]); {0}", number[0, 1, 1]); {0}", number[0, 1, 2]); {0}", number[0, 1, 3]); {0}\n", number[0, 1, 4]); {0}", number[0, 2, 0]); {0}", number[0, 2, 1]); {0}", number[0, 2, 2]); {0}", number[0, 2, 3]); {0}\n", number[0, 2, 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]); {0}", number[1, 1, 0]); {0}", number[1, 1, 1]); {0}", number[1, 1, 2]); {0}", number[1, 1, 3]); {0}\n", number[1, 1, 4]); {0}", number[1, 2, 0]); {0}", number[1, 2, 1]); {0}", number[1, 2, 2]); {0}", number[1, 2, 3]); {0}\n", number[1, 2, 4]);

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

C# 3.0 Practical Learning

574

Number[0][1][0] Number[0][1][1] Number[0][1][2] Number[0][1][3] Number[0][1][4] Number[0][2][0] Number[0][2][1] Number[0][2][2] Number[0][2][3] Number[0][2][4] Number[1][0][0] Number[1][0][1] Number[1][0][2] Number[1][0][3] Number[1][0][4] Number[1][1][0] Number[1][1][1] Number[1][1][2] Number[1][1][3] Number[1][1][4] Number[1][2][0] Number[1][2][1] Number[1][2][2] Number[1][2][3] Number[1][2][4]

= = = = = = = = = = = = = = = = = = = = = = = = =

-378.05 48.14 634.18 762.48 83.02 64.92 -7.44 86.74 -534.6 386.73 48.02 120.44 38.62 526.82 1704.62 56.85 105.48 363.31 172.62 128.48 906.68 47.12 -166.07 4444.26 408.62

Press any key to continue . . .

Since the lists are nested, if you want to use loops to access the members of the array, you can nest the for loops to incrementally access the values. Here is an example:
using System; public static class Exercise { static int Main(string[] args) { var Number = new double[2, 3, 5]; Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, Number[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0] 1] 2] 3] 4] 0] 1] 2] 3] 4] 0] 1] 2] 3] 4] = = = = = = = = = = = = = = = 12.44; 525.38; -6.28; 2448.32; 632.04; -378.05; 48.14; 634.18; 762.48; 83.02; 64.92; -7.44; 86.74; -534.60; 386.73;

C# 3.0 Practical Learning

575

Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1, Number[1,

0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,

0] 1] 2] 3] 4] 0] 1] 2] 3] 4] 0] 1] 2] 3] 4]

= = = = = = = = = = = = = = =

48.02; 120.44; 38.62; 526.82; 1704.62; 56.85; 105.48; 363.31; 172.62; 128.48; 906.68; 47.12; -166.07; 4444.26; 408.62;

for(int Outside = 0; Outside < 2; Outside++) for(int Inside = 0; Inside < 3; Inside++) for(int Value = 0; Value < 5; Value++) Console.WriteLine("Number = {0}", Number[Outside, Inside, Value]); return 0; } }

This would produce:
Number = 12.44 Number = 525.38 Number = -6.28 Number = 2448.32 Number = 632.04 Number = -378.05 Number = 48.14 Number = 634.18 Number = 762.48 Number = 83.02 Number = 64.92 Number = -7.44 Number = 86.74 Number = -534.6 Number = 386.73 Number = 48.02 Number = 120.44 Number = 38.62 Number = 526.82 Number = 1704.62 Number = 56.85 Number = 105.48 Number = 363.31 Number = 172.62 Number = 128.48 Number = 906.68 Number = 47.12 Number = -166.07 Number = 4444.26 Number = 408.62 Press any key to continue . . .

C# 3.0 Practical Learning

576

To make the result easier to read, we could use code as follows:
using System; public static class Exercise { static int Main(string[] args) { var Number = new double[2, 3, 5]; . . . No Change for(int Outside = 0; Outside < 2; Outside++) for(int Inside = 0; Inside < 3; Inside++) for (int Value = 0; Value < 5; Value++) { Console.WriteLine("Number[{0}][{1}][{2}] = {3}", Outside, Inside, Value, Number[Outside, Inside, if (Value % 5 == 0) Console.WriteLine();

Value]);

} return 0; } }

To use a foreach operator, access only each member to get to it. Here is an example:
using System; public static class Exercise { static int Main(string[] args) { var Numbers = new double[2, 3, 5]; . . . No Change foreach (var Value in Numbers) Console.WriteLine("Number: {0}", Value); } } return 0;

Multidimensional Arrays and Classes
Introduction
Like an array of a primitive type, a multidimensional array can be made a field of a class. You can primarily declare it without initializing it. Here is an example:
public class TriangleInCoordinateSystem

C# 3.0 Practical Learning

577

{ } private int[,] Points;

This indicates a two-dimensional array field: the array will contain two lists but we don't know (yet) how many members each array will contain. Therefore, if you want, when creating the array, you can specify its dimension by assigning it a second pair of square brackets using the new operator and the data type. Here is an example:
public class TriangleInCoordinateSystem { private int[,] Points = new int[3, 2]; }

You can also use a method of the class or a constructor to indicate the size of the array. Here is an example:
public class TriangleInCoordinateSystem { private int[,] Points; public TriangleInCoordinateSystem() { Points = new int[3, 2]; } }

To initialize the array, you can access each member using the square brackets as we saw in the previous sections. Here is an example:
public class TriangleInCoordinateSystem { private int[,] Points; public TriangleInCoordinateSystem() { Points = new int[3, 2]; Points[0, Points[0, Points[1, Points[1, Points[2, Points[2, 0] 1] 0] 1] 0] 1] = -2; // A(x, ) = -3; // A( , y) = 5; // B(x, ) = 1; // B( , y) = 4; // C(x, ) = -2; // C( , y)

} }

After initializing the array, you can use it as you see fit. For example, you can display its values to the user. Here is an example:
using System; public class TriangleInCoordinateSystem { private int[,] Points; public TriangleInCoordinateSystem() { Points = new int[3, 2];

C# 3.0 Practical Learning

578

Points[0, Points[0, Points[1, Points[1, Points[2, Points[2, }

0] 1] 0] 1] 0] 1]

= -2; // A(x, ) = -3; // A( , y) = 5; // B(x, ) = 1; // B( , y) = 4; // C(x, ) = -2; // C( , y)

}

public void ShowPoints() { Console.WriteLine("Coordinates of the Triangle"); Console.WriteLine("A({0}, {1})", Points[0, 0], Points[0, 1]); Console.WriteLine("B({0}, {1})", Points[1, 0], Points[1, 1]); Console.WriteLine("C({0}, {1})", Points[2, 0], Points[2, 1]); }

public static class Exercise { static int Main(string[] args) { var Triangle = new TriangleInCoordinateSystem(); Triangle.ShowPoints(); return 0; } }

This would produce:
Coordinates of the Triangle A(-2, -3) B(5, 1) C(4, -2) Press any key to continue . . .

A Multidimensional Array as Argument
A multidimensional array can be passed as argument. When creating the method, in its parentheses, enter the data type followed by the square brackets. In the square brackets, enter one comma for a two-dimensional array, two or more commas, as necessary, for a three-dimensional arrays as necessary. Here is an example:
public class TriangleInCoordinateSystem { public void ShowPoints(int[,] Coords) { } }

When defining the method, in its body, you can use the array as you see fit, such as displaying its values. Here is an example:
public class TriangleInCoordinateSystem { public void ShowPoints(int[,] Coords)

C# 3.0 Practical Learning

579

{ Console.WriteLine("Coordinates of the Triangle"); Console.WriteLine("A({0}, {1})", Coords[0, 0], Coords[0, 1]); Console.WriteLine("B({0}, {1})", Coords[1, 0], Coords[1, 1]); Console.WriteLine("C({0}, {1})", Coords[2, 0], Coords[2, 1]); } }

To call this type of method, pass only the name of the array. As indicated with one-dimensional arrays, when passing an multi-dimensional array argument, the array is treated as a reference. This makes it possible for the method to modify the array and return it changed. If you want to indicate that the array is passed by reference, you can precede its name in the parentheses by the the ref keyword. Here is an example:
using System; public class TriangleInCoordinateSystem { private int[,] Points; public void CreateTriangle(ref int[,] Points) { Points[0, Points[0, Points[1, Points[1, Points[2, Points[2, } public void ShowPoints(int[,] Coords) { Console.WriteLine("Coordinates of the Triangle"); Console.WriteLine("A({0}, {1})", Coords[0, 0], Coords[0, 1]); Console.WriteLine("B({0}, {1})", Coords[1, 0], Coords[1, 1]); Console.WriteLine("C({0}, {1})", Coords[2, 0], Coords[2, 1]); } 0] 1] 0] 1] 0] 1] = -2; // A(x, ) = -3; // A( , y) = 5; // B(x, ) = 1; // B( , y) = 4; // C(x, ) = -2; // C( , y)

}

public static class Exercise { static int Main(string[] args) { var Coordinates = new int[3, 2]; var Triangle = new TriangleInCoordinateSystem(); Triangle.CreateTriangle(ref Coordinates); Triangle.ShowPoints(Coordinates); } } return 0;

Returning a Multi-Dimensional Array
C# 3.0 Practical Learning
580

You can return a multi-dimensional array from a method. When creating the method, before its name, specify the data type followed by square brackets. In the square brackets, enter the necessary number of commas. Here is an example:
using System; public class TriangleInCoordinateSystem { public int[,] CreateTriangle() { } }

In the body of the method, you can do what you want but, before exiting it, you must return an array of the same type that was created. When calling the method, you can assign it to an array of the same type it returns. Here is an example:
using System; public class TriangleInCoordinateSystem { public int[,] CreateTriangle() { var Points = new int[3,2]; Points[0, Points[0, Points[1, Points[1, Points[2, Points[2, } 0] 1] 0] 1] 0] 1] = = = = = = 6; 1; 2; 3; 1; 4; // // // // // // A(x, A( , B(x, B( , C(x, C( , ) y) ) y) ) y)

return Points;

public void ShowPoints(int[,] Coords) { Console.WriteLine("Coordinates of the Triangle"); Console.WriteLine("A({0}, {1})", Coords[0, 0], Coords[0, 1]); Console.WriteLine("B({0}, {1})", Coords[1, 0], Coords[1, 1]); Console.WriteLine("C({0}, {1})", Coords[2, 0], Coords[2, 1]); } } public static class Exercise { static int Main(string[] args) { var Coordinates = new int[3, 2]; var Triangle = new TriangleInCoordinateSystem(); Coordinates = Triangle.CreateTriangle(); Triangle.ShowPoints(Coordinates); return 0; }

C# 3.0 Practical Learning

581

}

This would produce:
Coordinates of the Triangle A(6, 1) B(2, 3) C(1, 4) Press any key to continue . . .

A Multidimensional Array of Objects
A Variable of a Multidimensional Array of Objects
As done for primitive data types, you can create a multi-dimensional array where each member is of a class type. Of course you can use an existing class or you must first create a class. Here is an example:
public class Point { private int XCoord; private int YCoord; public int x { get { return XCoord; } set { XCoord = value; } } public int y { get { return YCoord; } set { YCoord = value; } }

}

To create a multidimensional array of objects without initializing it, you can use the following formula:
ClassName[,] VariableName;

If you know the number of instances of the class that the array will use, you can use the following formula:
ClassName[,] VariableName = new ClassName[Number1,Number2];

Or you can use the var keyword in the following formula:
var VariableName = new DataType[Number1,Number2];

The ClassName factor is the name of the class that will make up each member of the array. The other sections follow the same rules we reviewed for the primitive types. For example, you can create an array without allocating memory for it as follows:
public static class Exercise

C# 3.0 Practical Learning

582

{ static int Main(string[] args) { Point[,] Line; } } return 0;

If you know the number of members that the array will contain, you can use the right pair of square brackets, in which case you can specify the name of the class or use the var keyword and omit the left square brackets. Here is an example:
public static class Exercise { static int Main(string[] args) { var Line = new Point[2, 2]; } } return 0;

This declaration creates a two-dimensional array of two Point objects: The array contains two lists and each list contains two Points. To initialize a multidimensional array of objects, you can access each array member using its index, allocate memory for it using the new operator. After allocating memory for the member, you can then access its fields or properties to initialize it. Here is an example:
using System; public class Point { private int XCoord; private int YCoord; public int x { get { return XCoord; } set { XCoord = value; } } public int y { get { return YCoord; } set { YCoord = value; } }

}

public static class Exercise { static int Main(string[] args) { var Line = new Point[2, 2]; Line[0, 0] = new Point(); // First Point A

C# 3.0 Practical Learning

583

Line[0, Line[0, Line[0, Line[0, Line[0, }

0].x 0].y 1] = 1].x 1].y

= -3; = 8; new Point(); = 4; = -5;

// // // // //

A(x, ) A( , y) Second Point B B(x, ) B( , y)

return 0; }

You can also initialize the array when creating it. Before doing this, you would need a constructor of the class and the constructor must take the argument(s) that would be used to initialize each member of the array. To actually initialize the array, you would need a pair of external curly brackets for the main array. Inside of the external curly brackets, create a pair of curly brackets for each sub-dimension of the array. Inside the last curly brackets, use the new operator to access an instance of the class and call its constructor to specify the values of the instance of the class. Here is an example:
public class Point { private int XCoord; private int YCoord; public Point() { } public Point(int X, int Y) { XCoord = X; YCoord = Y; } public int x { get { return XCoord; } set { XCoord = value; } } public int y { get { return YCoord; } set { YCoord = value; } }

}

public static class Exercise { static int Main(string[] args) { var Line = new Point[,] { { new Point(-3, 8), new Point(4, -5) } };

C# 3.0 Practical Learning

584

return 0; } }

Accessing the Members of a Multidimensional Array of Objects
To access the members of a multidimensional array of objects, apply the square brackets to a particular member of the array and access the desired field or property of the class. Here is an example:
public static class Exercise { public static int Main(string[] args) { var Line = new Point[,] { { new Point(-3, 8), new Point(4, -5) } }; Console.WriteLine("Line =-="); Console.WriteLine("From A({0}, {1}) to B({2}, {3})", Line[0, 0].x, Line[0, 0].y, Line[0, 1].x, Line[0, 1].y); return 0; } }

This would produce:
Line =-= From A(-3, 8) to B(4, -5) Press any key to continue . . .

You can also use a loop to access the members of the array. To do this, create a first for loop that stops at the first dimension of the array - 1. Then, inside of a first for loop, nest a for loop for each subsequent dimension. Here is an example:
public static class Exercise { public static int Main(string[] args) { var Line = new Point[,] { { new Point(-3, 8), new Point(4, -5) } }; Console.WriteLine("The points of the line are:"); for(int i = 0; i < 1; i++) for(int j = 0; j < 2; j++) Console.Write("({0}, {1})", Line[i, j].x, Line[i, j].y); return 0; } }

C# 3.0 Practical Learning

585

This would produce:
The points of the line are: (-3, 8) (4, -5) Press any key to continue . . .

To apply a foreach operator, access only each member of the internal list. Here is an example:
public static class Exercise { static int Main(string[] args) { var Line = new Point[,] { { new Point(-3, 8), new Point(4, -5) } }; Console.WriteLine("The points of the line are:"); foreach (Point pt in Line) Console.WriteLine("({0}, {1})", pt.x, pt.y); return 0; } }

Multidimensional Arrays of Objects and Classes
Introduction
As done for primitive types, a multidimensional array of objects can be made a field of a class. You can declare the array without specifying its size. Here is an example:
public class Triangle { public Point[,] Vertices; }

If you know the dimensions that the array will have, you can specify them using the new operator at the same time you are creating the field. Here is an example:
public class Triangle { public Point[,] Vertices = new Point[3,2]; }

This creation signals a multidimensional array of Point objects. It will consist of three lists and each list will contain two Point objects To initialize the array, access each member by its index to allocate memory for it. Once you get the member, you access each one of its fields or properties and initialize it with the desired value. Here is an example: 586 C# 3.0 Practical Learning

public class Triangle { public Point[,] Vertices = new Point[3, 2]; public Triangle() { Vertices[0, 0] = Vertices[0, 0].x Vertices[0, 0].y Vertices[1, 0] = Vertices[1, 0].x Vertices[1, 0].y Vertices[2, 0] = Vertices[2, 0].x Vertices[2, 0].y }

new Point(); = -2; = -4; new Point(); = 3; = 5; new Point(); = 6; = -2;

// // // // // // // // //

Point A(x, y) A(x, ) A( , y) Point B(x, y) B(x, ) B( , y) Point C(x, y) C(x, ) C( , y)

}

If the class is equipped with the right constructor, you can use it to initialize each member of the array. Once the array is ready, you can access each members using its index and manipulate it. For example you can display its value(s) to the user. Here is an example:
using System; public class Point { private int XCoord; private int YCoord; public Point() { } public Point(int X, int Y) { XCoord = X; YCoord = Y; } public int x { get { return XCoord; } set { XCoord = value; } } public int y { get { return YCoord; } set { YCoord = value; } } } public class Triangle { public Point[,] Vertices = new Point[3, 2]; public Triangle()

C# 3.0 Practical Learning

587

{ Vertices[0, Vertices[0, Vertices[0, Vertices[1, Vertices[1, Vertices[1, Vertices[2, Vertices[2, Vertices[2, 0] = 0].x 0].y 0] = 0].x 0].y 0] = 0].x 0].y new Point(); = -2; = -4; new Point(); = 3; = 5; new Point(); = 6; = -2; // // // // // // // // // Point A(x, y) A(x, ) A( , y) Point B(x, y) B(x, ) B( , y) Point C(x, y) C(x, ) C( , y)

}

}

public void Identify() { Console.Write("Triangle Vertices: "); Console.WriteLine("A({0}, {1}), B({2}, {3}), and C({4}, {5})", Vertices[0, 0].x, Vertices[0, 0].y, Vertices[1, 0].x, Vertices[1, 0].y, Vertices[2, 0].x, Vertices[2, 0].y); }

public static class Exercise { static int Main(string[] args) { Triangle Tri = new Triangle(); Tri.Identify(); } } return 0;

This would produce:
Triangle Vertices: A(-2, -4), B(3, 5), and C(6, -2) Press any key to continue . . .

Passing a Multidimensional Array of Objects
You can pass a multidimensional array of objects as arguments. To do this, in the parentheses of the method, enter the class name followed by the square brackets. In the square brackets, type the appropriate number of commas. Here is an example:
public class Triangle { public void Create(Point[,] Points) { } }

In the body of the method, use the array as you we have done so far. You can access its members to get to its values. Here are examples:
public class Triangle { public void Create(Point[,] Points) {

C# 3.0 Practical Learning

588

Points[0, Points[0, Points[0, Points[1, Points[1, Points[1, Points[2, Points[2, Points[2, }

0] = 0].x 0].y 0] = 0].x 0].y 0] = 0].x 0].y

new Point(); = -2; = -4; new Point(); = 3; = 5; new Point(); = 6; = -2;

// // // // // // // // //

Point A(x, y) A(x, ) A( , y) Point B(x, y) B(x, ) B( , y) Point C(x, y) C(x, ) C( , y)

public void Identify(Point[,] Coordinate) { Console.Write("Triangle Vertices: "); Console.WriteLine("A({0}, {1}), B({2}, {3}), and C({4}, {5})", Coordinate[0, 0].x, Coordinate[0, 0].y, Coordinate[1, 0].x, Coordinate[1, 0].y, Coordinate[2, 0].x, Coordinate[2, 0].y); } } public static class Exercise { static int Main(string[] args) { Triangle Tri = new Triangle(); Point[,] Vertices = new Point[3, 2]; Tri.Create(Vertices); Tri.Identify(Vertices); } } return 0;

Remember that an array passed as argument is in fact passed by reference. You can indicate this by preceding it with the ref keyword.

Returning a Multidimensional Array of Objects
A method can return a multidimensional array of objects. If you are creating the method, before its name, type the name of the class followed by square brackets. Inside the square brackets, type the desired number of commas to indicate the dimension of the returned value. Here is an example:
public class Triangle { public Point[,] Create() { } }

After implementing the method, before exiting it, make sure it returns the type of array that it was indicated to produce. Here is an example:
using System; public class Point

C# 3.0 Practical Learning

589

{ private int XCoord; private int YCoord; public Point() { } public Point(int X, int Y) { XCoord = X; YCoord = Y; } public int x { get { return XCoord; } set { XCoord = value; } } public int y { get { return YCoord; } set { YCoord = value; } } } public class Triangle { public Point[,] Create() { var Points = new Point[3, 2]; Points[0, Points[0, Points[0, Points[1, Points[1, Points[1, Points[2, Points[2, Points[2, } 0] = 0].x 0].y 0] = 0].x 0].y 0] = 0].x 0].y new Point(); = -2; = -4; new Point(); = 3; = 5; new Point(); = 6; = -2; // // // // // // // // // Point A(x, y) A(x, ) A( , y) Point B(x, y) B(x, ) B( , y) Point C(x, y) C(x, ) C( , y)

return Points;

}

public void Identify(Point[,] Coordinate) { Console.Write("Triangle Vertices: "); Console.WriteLine("A({0}, {1}), B({2}, {3}), and C({4}, {5})", Coordinate[0, 0].x, Coordinate[0, 0].y, Coordinate[1, 0].x, Coordinate[1, 0].y, Coordinate[2, 0].x, Coordinate[2, 0].y); }

public static class Exercise { static int Main(string[] args) {

C# 3.0 Practical Learning

590

Triangle Tri = new Triangle(); Point[,] Vertices = Tri.Create(); Tri.Identify(Vertices); return 0; } }

Introduction to Jagged Arrays
Introduction
A jagged array is 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:
string[2][5] Members;

This declares a variable that represents two arrays and each array internally contains 5 arrays. Because each pair of square brackets is its own array, it can be used to create its own array with its own multidimensional array. Here is an example that creates a multidimensional array in the first dimension:
string[2,4][5] Members;

In the same way, the second square bracket can be used as a single or a multidimensional array. Here is an example:
string[2,4][5,12,8] Members;

Practical Learning: Introducing Jagged Arrays
1. Create a new Console Application named DepartmentStore4 2. Change the Program.cs file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore4 { public class Program { static int Main(string[] args) { long ItemID = 0; string Description = "Unknown";

C# 3.0 Practical Learning

591

double Price = 0.00D; Console.WriteLine("Receipt"); Console.WriteLine("Item Number: {0}", ItemID); Console.WriteLine("Description: {0}", Description); Console.WriteLine("Unit Price: {0:C}\n", Price);

} } }

3. Execute the application to see the result. This would produce:
Receipt Item Number: 0 Description: Unknown Unit Price: $0.00

4. Close the DOS window

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 pair of 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; public class Exercise { static int Main(string[] args) { string[][] Members = new string[2][]; return 0; } }

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; public class Exercise { static int Main(string[] args) { string[][] Members = new string[2][]{ new string[]{"Celeste", "Mathurin", "Alex", "Germain"}, new string[]{"Jeremy", "Mathew", "Anselme", "Frederique"} }; return 0;

C# 3.0 Practical Learning

592

} }

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:
public class Exercise { static int Main(string[] args) { string[][] Members = new string[2][]; Members[0] = new string[]{"Celeste", "Mathurin", "Alex", "Germain"}; Members[1] = new string[]{"Jeremy", "Mathew", "Anselme", "Frederique"}; } } return 0;

Practical Learning: Initializing a Jagged Array
1. To declare and initialize jagged arrays, change the file as follows:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore4 { public class Program { static int Main(string[] args) { long ItemID = 0; string Description = "Unknown"; double Price = 0.00D; // // // // // // // // // // // // // // // // 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# 3.0 Practical Learning

593

// 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" } } };

C# 3.0 Practical Learning

594

double[][][] UnitPrice = new double[2][][] { new double[][] { new double[] { 275.25, 180.00, 50.00, 265.00, 245.55 }, new double[] { 45.55, 25.65, 34.55, 28.55, 24.95 } }, new double[][] { new double[] { 45.75, 25.00, 65.55, 9.75, 165.75 }, new double[] { 265.15, 35.55, 24.95, 48.75, 32.50 } } }; Console.WriteLine("Receipt"); Console.WriteLine("Item Number: {0}", ItemID); Console.WriteLine("Description: {0}", Description); Console.WriteLine("Unit Price: {0:C}\n", Price); } } }

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 accessed with a multiple index, depending on how the array was created. Both the external and the internal lists are zero-based. Here is an example:
using System; public class Exercise { static int Main(string[] args) { 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 return 0; } 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[0][0]); {0}", Members[1][1]); {0}", Members[1][2]); {0}\n", Members[1][3]);

C# 3.0 Practical Learning

595

}

This would produce:
Member Member Member Member Member Member Member Member 1: 2: 3: 4: 5: 6: 7: 8: Celeste Mathurin Alex Germain Celeste Mathew Anselme Frederique

Press any key to continue . . .

You can also use some loops to access each member of the array. Here is an example:
using System; public static class Exercise { static int Main(string[] args) { string[][] Members = new string[2][]; Members[0] = new string[] { "Celeste", "Mathurin", "Alex", "Germain" }; Members[1] = new string[] { "Jeremy", "Mathew", "Anselme", "Frederique" }; for (int External = 0; External < 2; External++) for (int Internal = 0; Internal < 4; Internal++) Console.WriteLine("Name: {0}", Members[External] [Internal]); } } return 0;

If you want to use a foreach operator, you must access each array by its index. The external array can be accessed using a-zero based index and remember that you are accessing a whole array. Here is an example:
using System; public static class Exercise { static int Main(string[] args) { string[][] Members = new string[2][]; Members[0] = new string[] { "Celeste", "Mathurin", "Alex", "Germain" }; Members[1] = new string[] { "Jeremy", "Mathew", "Anselme", "Frederique" }; foreach (string Name in Members[0]) Console.WriteLine("Member: {0}", Name);

C# 3.0 Practical Learning

596

return 0; } }

This would produce:
Member: Celeste Member: Mathurin Member: Alex Member: Germain Press any key to continue . . .

To access the second array, apply its index as ArrayName[1].

Practical Learning: Using a Jagged Array
1. To process the members of a jagged array, make the following changes to the file:
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace DepartmentStore4 { public class Program { static int Main(string[] args) { long ItemID = 0; string Description = "Unknown"; double Price = 0.00D; string Category = "Category"; // // // // // // // // // // // // // // // // // 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[][] {

C# 3.0 Practical Learning

597

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" } } }; double[][][] UnitPrice = new double[2][][] { new double[][] { new double[] { 275.25, 180.00, 50.00, 265.00, 245.55 },

C# 3.0 Practical Learning

598

new double[] { 45.55, 25.65, 34.55, 28.55, 24.95 } }, new double[][] { new double[] { 45.75, 25.00, 65.55, 9.75, 165.75 }, new double[] { 265.15, 35.55, 24.95, 48.75, 32.50 } } }; // 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}", Description); Console.WriteLine("Unit Price: {0:C}\n", Price);

2. Execute the application and test it. Here is an example:
Enter Item Number: 448937

C# 3.0 Practical Learning

599

Receipt Item Number: Category: Description: Unit Price:

448937 Boys Carpenter Jeans $24.95

Press any key to continue . . .

3. Close the DOS window

C# 3.0 Practical Learning

600

The Array Class
Introduction to the Array Class
Overview
In the previous lessons, we saw how to create and initialize arrays. To assist with the use and management of arrays, you can combine the array features of the C# language and support from the .NET Framework. To support arrays, the .NET Framework provides a class of the same name. The Array class is defined in the System namespace of the System.dll assembly. When you create an array, you are in fact declaring a variable of type Array. Based on this, since an array variable is an object of a class type, you can use the characteristics of the Array class to create an array and/or to manipulate the values stored in the variable. You can create an array using any of the techniques we saw in the previous lessons, or you can use the Array class.

To assist you with creating an array, the Array class is equipped with the CreateInstance() method that comes in various versions. To create a onedimensional array whose members are zero-based, you can use the following version:
public static Array CreateInstance(Type elementType, int length);

The first argument is used to specify the type of array you want to create. Since it is declared as Type, you can use the typeof operator to cast your type. The second argument specifies the number of members of the array. Using the Array class, you can create an array as follows:
using System; public class Exercise { static int Main(string[] args) { Array Numbers = Array.CreateInstance(typeof(double), length); } } return 0;

You can also use the var keyword to declare the variable:
using System;

C# 3.0 Practical Learning

601

public class Exercise { static int Main(string[] args) { var Numbers = Array.CreateInstance(typeof(double), length); } } return 0;

The Length of an Array
We saw that if you declare a variable for an array but don't initialize it, you must specify the number of elements of the array. This number is passed inside the second pair of square brackets, as a constant integer. Here is an example:
using System; public class Exercise { static int Main(string[] args) { var Numbers = new double[5]; return 0; } }

If you use the Array class to create an array, you must pass this constant integer as the second argument of the CreateInstance() method from the the above version. Here is an example:
using System; public class Exercise { static int Main(string[] args) { var Numbers = Array.CreateInstance(typeof(double), 5); } } return 0;

If the array exists already, that is, if you have already created the array or you are using an array created by someone else, to find out the number of items it contains, you can access its Length property. Therefore, the length of an array is the number of elements it contains. Alternatively, you can call the Array.GetLength() method. Its syntax is:
public int GetLength(int dimension);

For a one-dimensional array, you must pass the argument as 0. This method returns a 32-bit integer that represents the number of items in the array. C# 3.0 Practical Learning
602

The Rank of an Array
We have seen that the square brackets are used to specify that you are declaring an array. If you are creating a one-dimensional array, we saw that you could type a number in the square bracket. If you are creating a twodimensional 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 placeholder 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 provides the Rank property. Therefore, to know the dimension of an existing array, you can access its Rank.

Fundamental Operations on an Array
Adding Items to an Array
Before using a class, it must have values or members in it. In the previous lesson, we saw that, to initialize an array, you open the curly brackets and list its members separated by commas, or you could access each member and assign it the desired value. To support the ability to add members to an array, the Array is equipped with a method named SetValue() that comes in different versions. To add a new item to a the type of array we have used so far, you can call the following version of the Array.SetValue() method:
public void SetValue(object value, int index);

The first argument is the value to add to the list. The second argument is the index of the member to be added. The first item has index 1; the second item has index 2, and so on. Here is an example:
using System; public class Exercise { static int Main(string[] args) { var Numbers = Array.CreateInstance(typeof(double), 5); Numbers.SetValue(7628.937, 0); Numbers.SetValue(6.48, 1); Numbers.SetValue(574.9, 2); Numbers.SetValue(293749.064, 3); Numbers.SetValue(0.70257, 4); } } return 0;

C# 3.0 Practical Learning

603

We indicated that whenever you create an array, you are in fact declaring an instance of the Array class. Therefore, even if you create an array using the square bracket formula we used in the previous lesson, you can call the SetValue() method to specify any member of the array. Here is an example:
using System; public class Exercise { static int Main(string[] args) { var Numbers = new double[5]; Numbers.SetValue(7628.937, 0); Numbers.SetValue(6.48, 1); Numbers.SetValue(574.9, 2); Numbers.SetValue(293749.064, 3); Numbers.SetValue(0.70257, 4); return 0; } }

The Array class provides a SetValue() version for each corresponding CreateInstance() method we reviewed earlier.

Accessing the Members of an Array
Once the array is initialized, you can access its members and do what you want with their values. To support the ability to retrieve the value of a member of an array, the Array class is equipped with a method named GetValue that is overloaded with a version corresponding to each version of the CreateInstance() and the SetValue() methods. For example, to access the values stored in a one-dimensional array, you can call call this version:
public object GetValue(int index);

The index argument is the zero-based index of the member whose value you want to access. Here is an example:
using System; public class Exercise { static int Main(string[] args) { var Numbers = new double[5]; Numbers.SetValue(7628.937, 0); Numbers.SetValue(6.48, 1); Numbers.SetValue(574.9, 2); Numbers.SetValue(293749.064, 3); Numbers.SetValue(0.70257, 4); Console.WriteLine("Number: {0}", Numbers.GetValue(0)); } return 0;

C# 3.0 Practical Learning

604

}

When calling the Array.GetValue() method, if you pass an invalid value, the compiler would throw an IndexOutOfRangeException exception. Just as you can access one member of the array, you can access any member using its index. Here is an example that uses a for loop and the Length property to know the number of members of an array:
using System; public class Exercise { static int Main(string[] args) { //var Numbers = Array.CreateInstance(typeof(double), 5); var Numbers = new double[5]; Numbers.SetValue(7628.937, 0); Numbers.SetValue(6.48, 1); Numbers.SetValue(574.9, 2); Numbers.SetValue(293749.064, 3); Numbers.SetValue(0.70257, 4); for(int i = 0; i < Numbers.Length; i++) Console.WriteLine("Number: {0}", Numbers.GetValue(i)); return 0; } }

If using the foreach operator, you don't need the GetValue() method. Here is an example:
using System; public class Exercise { static int Main(string[] args) { var Numbers = new double[5]; Numbers.SetValue(7628.937, 0); Numbers.SetValue(6.48, 1); Numbers.SetValue(574.9, 2); Numbers.SetValue(293749.064, 3); Numbers.SetValue(0.70257, 4); foreach(var Number in Numbers) Console.WriteLine("Number: {0}", Number); } } return 0;

Multidimensional Arrays

C# 3.0 Practical Learning

605

Two-Dimensional Arrays
The Array class supports the creation of any of the types of arrays we saw in the previous lessons. In the previous lesson, we saw that a two-dimensional array was an array made of two lists:
using System; public static class Exercise { public static int Main(string[] args) { var Members = new string[List1Length, List2Length]; } } return 0;

To create such an array using the Array class, you can use the following version of the Array.CreateInstance() method:
public static Array CreateInstance(Type elementType, int length1, int length2)

The first argument is the type of array you want to create. The second argument is the length of the first list. The third argument is the length of the second list. Here is an example of using it:
using System; public static class Exercise { public static int Main(string[] args) { var Members = Array.CreateInstance(typeof(string), 2, 4); } } return 0;

To specify the values of a two-dimensional array, you can use the following version of the Array.SetValue() method:
public void SetValue(object value, int index1, int index2)

The first argument is the value you want to add. The second argument is the index of the list. The second argument is the index of the element that is being added. Here is an example:
using System; public static class Exercise { public static int Main(string[] args) { var Members = Array.CreateInstance(typeof(string), 2, 4); Members.SetValue("Celeste", 0, 0); // 1st List - 1st Element Members.SetValue("Mathurin", 0, 1); // 1st List - 2nd Element

C# 3.0 Practical Learning

606

Members.SetValue("Alex", 0, 2); Members.SetValue("Germain",0, 3);

// 1st List - 3rd Element // 1st List - 4th Element

Members.SetValue("Jeremy", 1, 0); // 2nd List - 1st Element Members.SetValue("Mathew", 1, 1); // 1st List - 2nd Element Members.SetValue("Anselme", 1, 2); // 1st List - 3rd Element Members.SetValue("Frederique", 1, 3);// 1st List - 4th Element return 0; } }

Just as mentioned for the one-dimensional array, you can use the square brackets to create the array but call the SetValue() method to specify the value of each element. To access a member of a two-dimensional array created with the Array.SetValue() method, you use the following version of the Array.GetValue() method:
public Object GetValue(int index1, int index2)

This method takes two arguments. The first argument is the index of the list where the desired member resides. The second argument is the index of the element itself. Here is an example:
using System; public static class Exercise { public static int Main(string[] args) { var Members = Array.CreateInstance(typeof(string), 2, 4); Members.SetValue("Celeste", 0, 0); Members.SetValue("Mathurin", 0, 1); Members.SetValue("Alex", 0, 2); Members.SetValue("Germain",0, 3); // // // // 1st 1st 1st 1st List List List List 1st 2nd 3rd 4th Element Element Element Element

Members.SetValue("Jeremy", 1, 0); // 2nd List - 1st Element Members.SetValue("Mathew", 1, 1); // 1st List - 2nd Element Members.SetValue("Anselme", 1, 2); // 1st List - 3rd Element Members.SetValue("Frederique", 1, 3);// 1st List - 4th Element Console.WriteLine("Member: {0}", Members.GetValue(0, 2)); return 0; } }

To access each member of the list, you can use two for loops. Use the first loop to access each list. Nest a second loop to it to access each member. To get the dimension of the main list, you can call the Array.GetLength() method and specify its argument as 0. For the internal loop, pass 1 as the argument to the Array.GetLength() method. Here is an example:
using System; public static class Exercise {

C# 3.0 Practical Learning

607

public static int Main(string[] args) { var Members = Array.CreateInstance(typeof(string), 2, 4); Members.SetValue("Celeste", 0, 0); Members.SetValue("Mathurin", 0, 1); Members.SetValue("Alex", 0, 2); Members.SetValue("Germain",0, 3); // // // // 1st 1st 1st 1st List List List List 1st 2nd 3rd 4th Element Element Element Element

Members.SetValue("Jeremy", 1, 0); // 2nd List - 1st Element Members.SetValue("Mathew", 1, 1); // 1st List - 2nd Element Members.SetValue("Anselme", 1, 2); // 1st List - 3rd Element Members.SetValue("Frederique", 1, 3);// 1st List - 4th Element for(int List = 0; List < Members.GetLength(0); List++) for(int Element = 0; Element < Members.GetLength(1); Element+ Console.WriteLine("Member: {0}", Members.GetValue(List , Element )); return 0; } }

+)

You can also use a foreach operator to access each member of the array. When using it, there is no need for a counter. Here is an example:
using System; public static class Exercise { public static int Main(string[] args) { var Members = Array.CreateInstance(typeof(string), 2, 4); Members.SetValue("Celeste", 0, 0); Members.SetValue("Mathurin", 0, 1); Members.SetValue("Alex", 0, 2); Members.SetValue("Germain",0, 3); // // // // 1st 1st 1st 1st List List List List 1st 2nd 3rd 4th Element Element Element Element

Members.SetValue("Jeremy", 1, 0); // 2nd List - 1st Element Members.SetValue("Mathew", 1, 1); // 1st List - 2nd Element Members.SetValue("Anselme", 1, 2); // 1st List - 3rd Element Members.SetValue("Frederique", 1, 3);// 1st List - 4th Element foreach (string Member in Members) Console.WriteLine("Member: {0}", Member); return 0; } }

Three-Dimensional Arrays
Instead of two dimensions, you may want to create a t