+ All Categories

C#

Date post: 19-Jul-2016
Category:
Upload: ratna-kiran
View: 4 times
Download: 0 times
Share this document with a friend
265
Chapter 1 Introduction to the Object-Oriented Approach Object-Oriented Programming (OOP) is one of the most popular methodologies in software development. It offers a powerful model for creating computer programs. It speeds the program development process, improves maintenance, and enhances reusability of programs. This chapter introduces object-oriented methodology and discusses the concepts of objects, classes, messages, and methods. It provides an overview of the phases involved in object-oriented analysis and design. This chapter also explains how to define classes in C#. Objectives In this chapter, you will learn to: Explain features of the object-oriented methodology Describe the phases of the object-oriented methodology Define classes in C# Object-Oriented Methodology Object-orientation is a software development methodology that is based on modeling a real-world system. An object is the core concept involved in object orientation. An object is the representation of a real-world entity or concept. For example, an employee, a window, a car, or a bird can be modeled as objects. You can think of an object-oriented model as a collection of objects and their inter-relationships. The Foundation of Object-Orientation Object-orientation is a type of methodology used for building software applications. An object-oriented program consists of classes, object, and methods. If you were asked to create a classroom, you will start by creating a room and defining its boundaries and features. Next, you will put together all the components, such as chairs, tables, and books. Similarly, if you want to create an aircraft or a high-rise building,
Transcript
Page 1: C#

Chapter 1

Introduction to the Object-Oriented Approach

Object-Oriented Programming (OOP) is one of the most popular methodologies in software development. It offers a powerful model for creating computer programs. It speeds the program development process, improves maintenance, and enhances reusability of programs.

This chapter introduces object-oriented methodology and discusses the concepts of objects, classes, messages, and methods. It provides an overview of the phases involved in object-oriented analysis and design. This chapter also explains how to define classes in C#.

Objectives

In this chapter, you will learn to:

Explain features of the object-oriented methodology Describe the phases of the object-oriented methodology Define classes in C#

Object-Oriented Methodology

Object-orientation is a software development methodology that is based on modeling a real-world system. An object is the core concept involved in object orientation. An object is the representation of a real-world entity or concept. For example, an employee, a window, a car, or a bird can be modeled as objects. You can think of an object-oriented model as a collection of objects and their inter-relationships.

The Foundation of Object-Orientation

Object-orientation is a type of methodology used for building software applications. An object-oriented program consists of classes, object, and methods.

If you were asked to create a classroom, you will start by creating a room and defining its boundaries and features. Next, you will put together all the components, such as chairs, tables, and books. Similarly, if you want to create an aircraft or a high-rise building, you can do so by putting together several components or parts. These components or parts are analogous to objects in the objected-oriented methodology.

The object-oriented methodology in software development revolves around a single concept called the object. Software is developed by breaking the application into component objects. These objects interact with each other when the whole application is put together.

An object is a combination of messages and data. Objects can receive and send messages and use messages to interact with each other. The messages can contain information that is to be passed to the recipient object.

Page 2: C#

Object

An object literally means a ‘material thing’ that is capable of being presented to the senses. For our purpose, an object is a tangible entity that may exhibit some well-defined behavior. For example, let us consider a tennis ball:

A tennis ball is a tangible entity, with a visible boundary A tennis ball has a specific defined purpose (such as bouncing) You can direct a specific action towards a tennis ball by hitting it with a racquet or by

tossing it

But the definition of an object is not limited to merely something that can be seen, held and touched, such as a tennis ball or a car. For the purpose of software development, the definition of an object needs refinement for example, consider the Acme Nut and Bolt Company? An organization does not have a visible boundary, unlike a tennis ball. While it does not possess a physical boundary, it does have a conceptual boundary. Like all organizations, it has a specific defined purpose, and one can direct a specific action towards it. Thus, the Acme Nut and Bolt Company is an object.

State, Behavior, and Identity of an object

According to Grady Booch, a renowned software architect, an object has the following characteristics:

It has a state It may display behavior It has a unique identity

The state of an object is indicated by a set of attributes and their values. For example, a chemical can characterized by it temperature, color and density. The behavior of a chemical refers to the change of it attributes over a period of time. A chemical also has state, such as solid, liquid or gas.

The preceding paragraph explains the first two points of the definition of an object by Grady Booch “An object has state, exhibits some well-defined behavior…”. Now, you will examine the next part of the definition – “…and has a unique identity.”

Each object has a unique identity and the identity of an object distinguishes the object from all other objects.

For example, you can take a car as an object. It can have states such as moving and stationary. It can accelerate, decelerate, turn right, or turn left, which is it behavior. The car also has an identity, such as a unique registration number.

Two objects may have the same behavior and state, but they will never have the same identity. The identity of an object does not change in its lifetime. For example, two tennis balls may have the same color, be made of the same material, have the same weight and the same circumference, and display the same behavior. However, they will have distinct identities (for example, one ball will have the factory seal number ‘A1897345’ and the other ‘S459454’.

Just a minute

Identify the possible states of the following objects:1. a cell phone2. a stereo

Page 3: C#

Answer:

1. States of a cell phone: Off, Ring, Vibrate and Call2. States of a stereo: Play, Pause, Rewind and Forward

Classes

Look at the world around you. It is full of objects of various shapes, sizes, colors and behavior. For example, the earth is inhabited by millions of animals. A zoologist cannot do any meaningful study of these objects without organizing this vast variety of animals found in the world in a logical manner. Thus, the zoologists have classified animals into kingdoms, genus, families and species.

All animals and birds, which are essentially objects, can be classified on the basis of their common attributes. For example, the peacock, the sparrow, and the kingfisher are all birds. All of them share characteristics that are common to the family of birds. All of them lay eggs, are covered with feathers, have hollow bone structures and have the ability to fly. Therefore, they share structural and behavioral similarities and belong to the class of Birds.

This is shown in the following figure:

From the preceding example, you may define a class as a declaration, a template, or a blueprint that can be used to classify objects. Similarly, Book is a class and ‘Gone with the wind’ and ‘Farewell to Arms’ are the objects of this class.

Consider a video game that involves two players, Tom and Mark, who fight with each other. Tom chooses a shotgun and Mark chooses a pistol as their weapons in the game. If you need to create an object model for this game, you can identify a total of four objects. They are Tom, Mark, the shot gun and the pistol.

The object Shotgun belongs to the class Firearms. It has certain attributes that are common with the pistol. However, a shotgun is a unique object. Both the shotgun and the pistol are examples or instances of firearms. Therefore, the shotgun and pistol are objects of the same class, as shown in the following figure.

Birds

Peacock KingfisherSparrow

The class - Birds

Page 4: C#

Messages and Methods

Objects do not exist is isolation. They interact with other objects. These interactions take place through messages. Grady Booch has defined behavior as follows:

“Behavior is how an object acts and reacts, in terms of its state changes and message passing.”

In the example of a video game, every time Tom attacks, Mark either attacks or defends himself.

When Tom attacks Mark, Mark receives a message and reacts to that message. The reaction can be exhibiting a particular behavior such as running, hiding, dodging, or fighting back. For example, when Tom attacks, Mark receives a message “Being Attacked”. Mark responds to this message by hiding. In this situation, hiding is a behavior exhibited by Mark. Therefore, behavior (also called method in object-oriented methodology) is simply a set of actions taken by the receiving object in response to a message.

Just a minute

Dr James and Mr. Hyde went to the railway station to book tickets for 3 rd December. At the railway station, they requested the clerk at the ticket counter to book 2 tickets for the Flying Express in the first class. Identify the following:

1. The possible receiver of the message in this situation2. The possible method that the receiver can use

Answer

1. The receiver of the message in this case will be the clerk at the ticket counter.2. The clerk will check if 2 tickets are available on the requested train in the desired class

and for the desired date. If the tickets are available, the clerk will enter the details (name, age, departure date and seat), confirm the reservation and collect the required fare.

Characteristics of the Object-Oriented Approach

As discussed earlier, an object has state, behavior and identity. An object is reusable. Therefore, an object exists as a stand-alone entity that can be used in any relevant context. For example, if you have a chair, you can use the same chair in an office, in a classroom, or in a garden.

Class: Firearms

Object: Pistol Object: Shotgun

Classes and Objects

Page 5: C#

An existing object can be used to create a similar object. For example, you have a simple wooden chair and you need to add a headrest to it. You do not need to create a new chair because you can easily add a headrest to the existing chair. This is known as resilience to change.

Realistic Modeling

Because you live in a world of objects, it logically follows that the object-oriented approach models the real world more accurately. The object-oriented approach allows you to identify entities as objects having attributes and behavior. Attributes and behavior typically depict how the objects acts and reacts. For example, the car is an object belonging to the class Vehicle. The car has attributes such as speed, color, and power. It displays behavior such as being stationary, moving slowly, or accelerating.

Reusability

In the software industry, using existing classes or objects from other applications saves resources spent in recreating the classes from scratch. Consider the following analogy:

Carcare is a leading car manufacturing company. Carcare manufactures 2 seater cars that are very popular among the consumers aged between 20 and 24. The company has decided to enter the market of family segment market and has decided to manufacture a 4 seater model.

Carcare can either design a new car for the family segment or convert the 2 seater model to 4 seater model. The cost involved in designing a new model is very high as compared to the cost involved in converting 2 seater model to 4 seater model.

Therefore, the management and the design team may decide to convert the 2 seater model into a family segment model as shown in the following figure:

The preceding scenario depicts the concept of reusability that is supported by the object-oriented approach. The process of creating a new class by adding some features to the existing class is

Two-seater Car

AttributesBehavior

Four-Seater Car

Two-seater Car - AttributesTwo-seater Car - Behavior

New AttributesNew Behavior

Example of reusability

Page 6: C#

known as inheritance. The benefit of reusability translates to savings in time and effort, which in turn results in cost benefits.

Just a minute

State whether the following situations demonstrate reusability.1. Recycling paper2. Pump Reusability (same pump is used in a well and in a fuel station)

Answer1. It does not represent reusability because the unusable paper s destroyed before paper is

recycling for use. The usable paper loses its identity and cannot be considered the same as recycling paper.

2. It represents reusability because a pump can be used for suction of water as well as petrol. It is not necessary to use to the same pump in both the cases. Two separate machines can be used because both belong to the ‘Pump’ class.

Resilience to change

The object-oriented approach allows system to evolve. When a change is suggested, the old system need not be completely abandoned. Consider the example of JoyToys, Inc, is a company that manufactures toys for children in the age group of 1 to 12. Its car toys are popular with children because of their attractive colors, shape and sound.

For a couple of years, the company had no cause for complain about the design of the toy car. However, due to the advancement in technology and increase in competition, the designers now want to stop manufacturing the old car because the market requirements have changed. They want the company to manufacture a car that has flashing lights and remotely controlled.

In the object-oriented system, this requirement does not mean that the new car needs to be build from scratch. The new features can be easily incorporated in the old toy car without modifying the color, shape and sound of the old toy car, as shown in the following figure:

Resilience to change also results in easier maintenance. This feature of object-oriented methodology is now known as extensibility. The ability of the class to inherit features from another class also makes object-oriented programs more extensible. For the same reason, even during construction, parts of system under development can be refined without any major changes to other parts.

Existence as Different forms

Using the object-oriented approach, objects can be made to respond differently to the same message. The response is decided upon based on the information or parameters provided with the message.

Note: Information is passed as parameters in a function. For a detailed functions and parameters, refer the subsequent chapters.

If a car collides against an object, the behavior of the car after the collision will depend on the speed of the car, and the nature of the object that hit the car. For example, if the car collides with another car at high speed, both the cars will be smashed and the drivers might get injured. On the other hand, if a car collides with a street light at a low speed, the impact would be less. This ability to react differently based on the information associated with the message is known as polymorphism.

Page 7: C#

Phases of object-oriented methodology

Before the actual development of any product, important steps such as analysis and design need to be performed. The following phases are involved in the object-oriented methodology:

Analysis Phase Design Phase Implementation Phase

Consider an aircraft manufacturing factory where a new jet liner is being assembled and several competent engineers and work men are working with specialized tools. Can you visualize them working on pure intuition, grabbing the tools, and sitting down to work immediately? Or, do you see them working according to a detailed design, on which they have spent hundreds of hours, and finally constructing the aircraft based on specific design.

For the safety of millions of people who fly everyday, it is recommended to use a detailed design. After all, it is comforting to know that a lot of thought has gone into first making a model on a paper and then translating the design into the physical jet liner. The same thing holds true for almost any item that is constructed. Similarly, designers put pen to paper before attacking the fabric with scissors. Architects spend hours drawing layouts of buildings on blueprints before the bricks are laid.

Therefore, the construction of software follows the same approach. The software industries still rely mainly on the paper-and-pencil approach in the upstream development phases.

It is this paper-and-pencil approach that is termed analysis and design. To analyze and design a system, you need to build a model of the system. The model is simpler than the system that is finally constructed. All the practical aspects of building a system for the real world can not be reflected in the design. However, this does not undermine the importance of design.

Analysis Phase

“The purpose of analysis is to provide a description of a problem. The description must be complete, consistent, readable, and reviewable by diverse interested parties, and testable against reality” – Mellor

The analysis or the object-oriented analysis (OOA) phase considers the system as a solution to a problem in its environment or domain. Broadly, analysis is a phase where users and developers of the system get together and arrive at a common understanding of the system. One of the end products of the analysis phase is the specification on how a system functions.

In the analysis phase, the developer concentrates on obtaining as much information as a possible about the problem. The developer has to identify the critical requirements. Analysis therefore involves meeting and interviewing the concerned persons to understand systems that are currently in operation, and identifying all the causes of problems (if any) in the current system.

The Design Phase

In the design phase, the developers of the system document their understanding of the system. Design generates the blue print of the system that is to be implemented.

The first step in creating an Object -Oriented Design (OOD) is the identification of classes and their inter-relationships.

Page 8: C#

Work in the design phase of software development is comparable to the work of an architect. The architect will need to create a blue print or a model of the building before the construction of the building starts.

The Implementation Phase

The design phase is followed by OOP, which is implementation phase. OOP provides specifications for writing programs in a programming language. One on the most popular languages used to write object-oriented programs C#.

During the implementation phase, programming is done as per the requirements gathered during the analysis and the design phases.

Many of the modern applications are built by using OOP. Developing complex, large-scale business systems can be simplified by using OOP techniques. Some of the applications that can be built by using OOP techniques are Computer Aided Design (CAD), Computer Aided Manufacturing (CAM), and Object-Oriented Databases.

Just a minute

As a member of a team that is developing software for DialCom Telecommunications, Inc., you have been assigned the task of creating a software module that accepts and displays customer details such as name, age, and phone number. Identify the class that you will create and the methods of the class.

Answer:

As per the problem statement, the class required is:

Customer

The class should have the methods to:

Accept customer details Display customer details

Introducing C#

Computer languages have come a long way since 1940s. Back then, scientists punched instructions into the mammoth, room-sized computer systems. These instructions were long series of zeros and ones. These machine language instructions are called the first generation of computer languages.

The 1950s saw the emergence of second generation of computer languages – assembly language – easy to write than the machine language but still extremely complicated for a common man. However, the computer could still understand only machine language. Therefore, the assembler software was developed to translate the code written in assembly language to machine language.

In 1967, Martin Richard developed a language called BPCL, for writing operating systems. An Operating system is a set of programs that manages the resources of a computer and its interactions with users. The era of the third generation computer languages had arrived. In 1970, Ken Thompson modified BPCL to create a new language called B. While working for Bell laboratories, Thompson teamed up with Dennis Ritchie and wrote an early version of UNIX operating system for a DEC-PDP-7 computer.

Page 9: C#

Dennis Ritchie was working on a project to further develop the UNIX operating system. He wanted a low level language like assembly language that could control hardware efficiently. At the same time, he wanted the language to provide the features of a high level language, that is, it should be able to run on different types of hardware. B had performance draw backs, so in 1972 he rewrote B and called it C. Therefore, C is categorized as both a second and third generation language. Thompson and Ritchie rewrote the UNIX operating system in C. In the years that followed C was widely accepted and used over different hardware platforms. This led to many variations of C. In 1989, the American National Standard Institute (ANSI), along with international standards organization (ISO), approved a machine-independent and standard version of C.

In the early 1980s, Bijarne Stroustrup of Bell Laboratories developed the C++ language. In his own words, “C++ was designed primarily so that m friends and I would not have to program in assembly, C, or various modern high-level languages. Its main purpose was to make writing good programs easier and more pleasant for the individual programmer.”

C++ was originally known as ‘C with classes’, because 2 languages contributed to its design – C, which provided low level features and Simula 67, which provided the class concept. C++ is an object-oriented language. Other object-oriented languages are Java, Smalltalk, and C#.

C#, also known as C-Sharp, is a programming language introduced by Microsoft. C# contains features similar to Java and C++. It is specially designed to work with Microsoft’s .NET platform.

Note: The .NET platform is aimed at providing internet users with web-enabled interface for applications and computing devices, such as mobile phones. It also provides developers, the ability to create reusable modules, thereby increasing productivity.

Compilers

All languages have a vocabulary, which is a list of words that have a specific meaning in that language. Languages also have their own grammar rules, which state the rules for combing words to form sentences. That is what ensures that whatever is spoken in particular language is interpreted by all people to understand the language. Similarly, programming languages also have vocabulary, which is referred to as a set of keywords of that language, and a grammar, which is referred to as syntax.

Does this mean that computers can directly interpret the instructions written in any programming languages? No, they cannot. Then, how do you ensure that a computer executes the instructions from a program as intended? What would you do if you got hold of a receipe for a delicious dish written in foreign language that you do not understand? You would get it translated to English or any other language you understand to be able to prepare the dish. Similarly, you need a translator to convert the instructions written in a programming language to machine language.

A compiler is a special program that processes the statements written in particular programming languages and converts them into machine language. Like everything else in the computer, the compiler also follows the input-process-output (I_P_O) cycle. It takes programming language instructions as input. These instructions can be executed by the computer. This process of conversion is called compilation. For each programming language, there is different compiler available. For example, for compiling a program written in the C language, you require a C compiler. For a Java program, you require a Java compiler. For C# programs, you will use the CSC compiler.

You will now learn to create classes in the C# language.

Page 10: C#

Classes in C#

Consider the following code example which defines a class:

Public class Hello{

public static void Main(string[] args){

System.Console.WriteLine(“Hello\n”);}

}

The preceding class declaration provides a method Main() that will display the message “Hello” on your screen. The parts of the preceding code need to be examined.

The Main() function

The first line of the code that a C# compiler looks for in the source file compiled is the Main function. This function is the entry point of the application.

The main function is ideally used to create objects and invoke member function.

The Class Keyword

The class keyword is used to declare a class. Keywords are reserved words that have a special meaning. Here, the class keyword defines the class Hello. The braces, knows as delimiters, are used to indicate the start and end of the class body.

Example:

Class Hello{

……….….…..

}

The class name

The class keyword is followed by the name of the class. In the preceding example, Hello is the name of the class defined by using the class keyword. When you create classes, you must consider the following naming conventions and rules.

Class Naming Conventions in C#

Class name should follow certain naming conventions are guidelines. A class name: Should be meaningful (strongly recommended) Should ideally be a noun. Can use either the Pascal case or the Camel case. In Pascal case, the first letter is

capitalized and the rest of the letters are in lower case, such as Myclass. In camel case, the first letter is in the lower case and the first letter of each subsequent word is capitalized, such as myClass.

Page 11: C#

Rules for naming classes in C#

Name of classes: Must begin with a letter. This letter may be followed by a sequence of letters, digits (0-9),

or “_”. The first character in a class name cannot be a digit. Must not contain any embedded space and any symbol like ? - + ! & # % ^ & * ( ) { }

[ ] : . ; “ ‘ / \. However, an underscore “_” can be used wherever a space is required. Must not use a keyword for a class name. For example, you cannot declare a class.

System.Console.WriteLine()

Console is a class that belongs to the system namespace. A namespace is a collection of classes. The system namespace contains the method WriteLine(), which displays the enclosed text on the screen. The console class has other methods, which are used for various input/output operations. The character(.) is used to access the function, WriteLine(), which is coded in the console class of the system namespace.

The preceding line can also be written as Console.WriteLine() is the statement using system is included as the first line of code.

The following code is an example Console.WriteLine ( ) :Console.writeLine(“Hello world \n”);

The preceding code will display on the screen.

Hello World

The Escape Characters

To display special characters such as the new line character or the backspace character, you need to use escape characters.

The following table lists the escape characters used in C#.

Escape Sequence Character Name\’ Single quotation mark\” Double quotation mark\\ Back slash\0 Null\a Alert\b Back Space\f Form Feed\n New line\r Carriage return\t Horizontal tab\v Vertical tab

The Escape Characters

Example of New line escape sequence

Console.WriteLine(“ Hello \n world”);

Page 12: C#

The preceding code will display the following message on the screen:

HelloWorld

Activity: creating Classes

Problem statement

As a member of a team that is developing for JoyToys, inc., you have been assigned the task of creating a bike module that accepts and displays bike details. Declare the Bike class and its member functions. The member function that accepts bike details should display the message “ Accepting Bike Details”. Similarly, the member function to display bike details on the screen should display the message “ Displaying Bike Details”.

Solution

The following code will create the Bike class with the required functions:

class Bike { void AcceptBikeDetails() { Console.WriteLine("Accepting Bike Details\n");

} void DisplayBikeDetails() { Console.WriteLine("Displaying Bike Details\n"); } }

Practice Questions

1. Which of the following is not a class?a. A Ford Ikon car with the registration number XXXXb. Fruitc. Mammald. Fish

2. Which method displays the message “Hello People” on the screen?a. Console.WriteLine("Hello People");b. System.WriteLine("Hello People");c. Console("Hello People");d. Console.writeline("Hello People");

3. Console is a ______________.a. Namespaceb. Classc. Functiond. Escape Sequence character

4. In a C# program, which is the first function to be executed?a. Main()b. Main()

Page 13: C#

c. Console.WriteLine()d. void AcceptBikeDetails()

5. Which of the following is used to denote a newline character?a. \bb. \nc. \vd. /n

Summary

In this chapter, you learned that According to the object-oriented approach, systems consist of component objects that

interact with each other. An object is an entity that may have a physical boundary. However, it should have the

following characteristics:o Stateo Behavioro Identity

A class consists of a set of objects that share a common structure and behavior If an object desires an action from another object, it sends a message to that object. The object that receives the message is called the receiver, and the set of actions taken

by the receiver constitutes the method. The features of the object-oriented approach are:

o Realistic modelingo Binding attributes and behavior togethero Reusabiltyo Resilience to changeo Existence as different forms

A model of a system is built in the stages of analysis and design. The purpose of the model is to help developers understand the reality that they are trying

to imitate In C#, a class is created by using the keyword class. It is identified by a name called the

class name. The console.WriteLine( ) method is used to display text on the screen Main( ) is first function which is executed in a C# program Escape characters are used to display special characters such as the newline character.

Exercises

Exercise 1

Analyze the process of making a call by using a pay phone. Identify the objects involved and the behavior of these objects. Also, identify the messages passed between the objects for interacting with each other.

Exercise 2

As a member of a team that is developing an automated ranking system of players in video game parlors, you have been assigned the tank of creating a module that accepts the details of the player after a game is over Declare a class player, which consists of three member

Page 14: C#

functions: AcceptPlayerDetail ( ) , ComparePlayerDetail ( ), and PrintPlayerRank ( ).Each of these functions should print the appropriate message on the screen.

Chapter 2

Creating Objects

An object is an instance of a class. You create objects to access member variables and member functions of a class.

The chapter discusses how to declare variables. It also discusses how to write and execute and execute C# program.

Objectives

In this chapter, you will learn to: Declare variables Write and execute C# programs

Declaring Variables

A variable is a location in the memory that has a name and contains a value. The value could be an integer, such as 27, a decimal, such as 9.85, or a character, such as ‘L’. A variable is associated with the data type that defines the type of data, which can be stored in a variable. For example, a variable called TennisPlayerName will ideally store characters, whereas a variable called High_Score will store numbers. A program refers to a variable by its name.

Naming Variables in C#

The following rules are used for naming variables in C#:

Must begin with a letter or an underscore(‘_’), which ay be followed by a sequence of letters, digits(0-9), or underscores. The first character in a variable name cannot be a digit.

Should not contain any embedded spaces or symbols such as ? ! @ # + - % ^ & * ( ) [ ] { } . , ; : “ ‘ / and \. However, an underscore can be used wherever a space is required, like high_score.

Must be unique. For example, to store four different numbers, four unique variable names need to be used. Uppercase letters are considered distinct from lowercase letters.

Can have any number of characters.

Keywords cannot be used as variables names. For examples, you cannot declare a variable named class because it is a keyword in C#.

Page 15: C#

The following are examples of valid variables names:

Game_levelHigh_scoreThis_variable_name_is_very_long

The following are examples of invalid names:

# score2strank

Note:

C# is a case-sensitive languages. This means that the variable TennisPlayerName is not the same as the variable tennisplayername.

Declaring and Initializing Variables

You can declare and initialize variables by using the following syntax:

<data_type> <variable_name> = <value>

In the preceding syntax, the <data_type> represents the kind of data type that will be stored in a variable and <value> specifies the value that needs to be stored in a variable.

Consider the following statement of variable declarations:

int age;;

The preceding statement declares the variable age of the int data type and initializing the variable with the value 0. The int data type is used to store numeric data.

Consider the following statement:

char choice = 'y';

The preceding statement declares the variable choice of the char data type and initializing the variable with the value y.

The data type represents the kind of data that will be stored in a variable.

Data Types in C#

C# provides various built-in data types. Built-in data types are the predefined data types.

The following table lists some of the built-in data types.

Predefined Type # Bytes Range of Values

Page 16: C#

char 2 0 and 65535

int 4 -2, 147, 483, 648 and 2, 147, 483, 647

float 4 -3.402823E+38 and -1.401298E-45 (For negative values)1.401298E-45 and 3.402823E + 38 (For positive values)

double 8 -1.79769313486232E308 to – 4.94065645841247E-324 (for negative values) and 4.94065645841247E-324 to 1.79769313486232E308 (for positive values)

bool 1 True or False

string Variable length 0-2 billion Unicode characters

Built-In Data Types

Built-in data types are represented at the machine level. The storage requirement, therefore, depends on the hardware. The #Bytes column in the preceding table depicts the bytes required to store the value in the memory.

Note

C# also provides user-defined data types. You will learn about user-defined data types in subsequent chapters.

Types of Data Types

C# supports 2 types of data types. The types of data types supported by C# are:

Value Types: They directly contain data. Some examples of the value types are char, int and float, which can be used for storing alphabets, integers, and floating point numbers, respectively. When you declare an variable int, the system allocated memory ti store the value. The following figure shows the memory allocation of an int variable.

Page 17: C#

Reference types: The types do not maintain data but theycontain reference to the variables, which are stored in memory. Using more than one variable, you can use reference types to refer to a memory allocation of a string value “ Hello” in a variable named str.

Table 2.6 creating objects

In the preceding figure, the value of the variable Str is stored in memory and the address of this memory is stored at another location.

Accepting and storing Values in Member Variables

To understand how to store value in variable, consider the following code snippet.

Int Number;Number = Convert.ToInt32(Console.ReadLine ( ) );

In the preceding code snippet, the Console.readLine ( ) is used to accept input from the user and store it in the number variable. Console.ReadLine( ) is a function of the console class, which is a part of the system namespace.

The Convet.ToInt32( ) converts the data entered by the user to the int data type.You need to perform conversion because Console.ReadLine( ) accepts the data in string format. The Convert ( ) method explicitly tells the compiler to convert one data tpe to other data type. This is called explicit conversion. The complier performs an implicit conversion automatically. For example, implicit conversion converts the int data type to float or float data type to int, automatically,

Writing and executing a C# program

In this section you will learn to write, compile and execute a C# program.

Creating a sample C# program

A C# program can be written by using Notepad. Consider the following code, which declares a car class and created the object MyCar of the same class:

using System;class Car

{

int Num;Num = 5;

5

Num

Memory allocated

Memory Allocation in Value Type

Page 18: C#

//Member Variablesstring Engine;int NoOfWheels;//Member Functions

public void AcceptDetails()

{

Console.WriteLine("Enter the Engine Model:");Engine = Console.ReadLine();Console.WriteLine("\nEnter the number of Wheels:");NoOfWheels = Convert.ToInt32(Console.ReadLine());

}

public void DisplayDetails()

{

Console.WriteLine("Enter the Engine Model:{0}", Engine);Console.WriteLine("\nEnter the number of Wheels:{0}", NoOfWheels );

}}

//Class used to instantiate the Car class

class ExecuteClass{

public static void Main()

{Car c = new Car();c.AcceptDetails();c.DisplayDetails();

}

}The output of the preceding code is as follows:

The using keyword

First statement in a typical C# program is:

using System;

The using keyword is used to include the namespaces in the program. Keywords are reserved words that have a special meaning. The statement, using System, declares that you can refer to the classes defined in the namespace without using the fully qualified name. A program can include using statements.

The class Keyword

Page 19: C#

The class keyword is used to declare a class. In the preceding code, the class keyword defines the class car. The braces, known as delimeters, are used to indicate start and end of the class body.

The comment Entry

Comments are a part of the program and are used to explain code. Compilers ignore comment entries. The following symbols are use to give a comment entry in C#:

// Comment TextOr/* This is the sample program to display addition of two numbersComment text */

If a comment entry spans more than one line, it has to be enclose within ‘/*’ and ‘*/’. The symbol ‘//’ treats the rest of code within the same line as a comment.

Member Varaibles

Variables are used to store data. Variables are also called the data members of a class. In the preceding code, class car has two member variables called engine and NoOfWheels. These member variables can be used to store data for a car.

Member Functions

A functions is a set of statements that performs a specific task in response to a message. The functions of a class are called member functions in C#. member functions are declared inside the class. The function declaration introduces the function in the class and the function defenition contains the function code.

The preceding code contains two member functions named AcceptDetails and DisplayDetails. These are declared and defined inside the class. Notice, the function definition contains code, which enclosed in a block. The block is enclosed withon braces ‘( )’.

Instantiating Class

In the preceding code, the ExecutiveClass class is declared with the Main ( ) method. The ExecutiveClass is used as a class from where the Car class can be instantiated. The first line of code that a C# compiler looks for in the source file compiled is the Main( ) function.

To use a class the members of a class, you need to create an object the class. Objects interact with each other by passing messages and by responding to the recived messages. Objects use methods to pass messages. In C#, the task of passing messages can be accomplished by using member functions.

All the objects of a class share the same copy of the member functions but they maintain a separate copy of the member variables in memory. The sharing of member functions and non sharing of member variables of classes and objects is shown in the following figure.

Table :A class and its objects 2.10 creating Objects.

Page 20: C#

In the preceding code, you have declared a class named Car. To create an object named MyCar of the type car, the following code is given in the main( ) method.

Car MyCar = new Car();

The member functions of the class are accessed through an object of the class by using the “.” Opertor, as shown in the following example:

MyCar.AcceptDetails ();MyCar.DisplayDetails ();

In the preceeding example, the object named and the “.” Operator are used to access the member function AcceptDetails( ) and DisplayDetails( ). This means the object MyCar of the class car has invoked the function AccpetDetails( ) and DisplayDetails( ). This function accepts the values of engine type and the number of wheels from the user and displays the same.

Note:

The preceding code invokes the member function which is written within the Main( ) function. Usually, member functions are declared and defined under the public access specifier. Access specifiers are used to determine if any other class can access the variables or function of a class.

Compiling and Executing C# Program

Member Function 1Member Function 2

Member Variable1Member Variable 2

Member Variable 1Member Variable 2

Member Variable 1Member Variable 2

Object Object

Page 21: C#

After writing a C# program in notepad, you need to compile and execute it to get the desired output. The complier converts the source code that you write in the machine code, which the computer can understand.

You need to perform the following steps to compile and execute a C# program:1. Save the code written in Notepad with an extension .cs.2. To compile the code, you need to go to the Visual Studio 2005 command prompt. Select

Start all programsVisual studio 2005Visual studio Tools Visual studio 2005 command prompt to compile this program.

3. In the Visual studio 2005 Command Prompt window, move to the location where the program file is saved

4. Compile the program file by using the following commandcsc ExecutiveClass.cs

5. To execute the code, type the following on the command prompt:ExecuteClass.exe

Activity: Creating a C# Program

Problem Statement

David is the member of a team that is developing the Automatic Ranking Software for a tennis tournament. You have been assigned the task of creating a program. The program should accept the following details of a tennis player and display it:

Name, containing a maximum of 25 characters Rank as an integer Winning average as a decimal value

Help David to create the program

Solution

To develop the required program, David needs to perform the following steps:1. Select Start All Programs Accessories Notepad2. Write the following program code in Notepad

using System;

class TennisPlayer

{

string TennisPlayerName;int Rank;decimal WinningAverage;

public void AcceptDetails()

{Console.WriteLine("\n Enter the name of the Tennis Player:");TennisPlayerName = Console.ReadLine();Console.WriteLine("\n Enter the Rank of the Player:");Rank = Convert.ToInt32(Console.ReadLine());Console.WriteLine("\n Enter the Winning Average:");

WinningAverage = Convert.ToDecimal(Console.ReadLine());}

public void DisplayDetails()

Page 22: C#

{ Console.WriteLine("\n Name of the Tennis Player:{0}", TennisPlayerName); Console.WriteLine("\n Rank of the Player:{0}", Rank); Console.WriteLine("\n Winning Average:{0}", WinningAverage); } public static void Main() { TennisPlayer t = new TennisPlayer(); t.AcceptDetails(); t.DisplayDetails(); }}

3. Select File Save to save the program file. The Save As dialog box opens4. Enter Tennisplayer.cs in the File name text box. The filename is saved with the .cs

extension, signifying that it is a C# program.5. Select Start all programsVisual studio 2005Visual studio Tools Visual

studio 2005 command prompt to compile this program6. In the Visual studio 2005 Command Prompt window, move to the location where the

program file is saved7. Compile the program file by using the following command

csc Tennisplayer.cs6. To execute the code, type the following on the command prompt:

Tennisplayer.exe8. Verify the output of the executed program

Practice Questions

1. In the statement, using System, System is a ________________________a. Namespaceb. Classc. Objectd. Keyword

2. Which is the following is not an example of value type?a. Charb. Intc. Floatd. String

3. The _________ compiler is used for C#.a. Ccb. Cscc. C++d. Cs

4. The statement //Hello World in a C# programa. Displays the text Hello World on the screenb. Is not executed by the compiler and will be treated as a commentc. Declares a variable Hello Worldd. Causes all code lines following it to be treated as comments

5. In which of the following datatype does the Console.ReadLine() function accept a value?a. intb. floatc. boold. string

Page 23: C#

Summary

In this chapter, you learned that: A variable is a named location in the memory that contains a specific value A data type defines the type of the data that can be stored in a variable The two types of data type are Value Type an Reference type The ReadLine() function is used to accept inputs from the user The using keyword is used to include namespaces in a program A namespace contains a set of related classes Member variables are declared inside the class body Comment entries are notes written by a programmer in code so that others reading that

code can understand it better An object is an instance of a class The compiler software translates a program written in a language, such as C#, into the

machine language.

Exercises

Exercise 1

Diaz Entertainment, Inc is developing a software application for toddlers that would enable them to identify and distinguish shapes and colors. You have defined the Geometrical_Shapes class as a part of developing the software. The following is the class definition:

using System;class Geometrical_Shapes{

double No_of_coordinates;double Area;string Color;

public void Create(){

//code to accept the user inputs and store the values in // the corresponding variables

}

public void Display(){

// Code to display the details of hte shape such as //no_of_coordinates, area and color

}

} The Geometrical_Shapes class definition contains errors and is incomplete. You need to fix the errors and complete the code in the Geometrical_Shapes class definition. You also need to write the Main() function, compile and execute the code

Exercise 2

Page 24: C#

Jim is developing software for automating the slot booking process for a video game parlor. s Customers fill the Booking Request Form with the details of the game, such as the name, number of players and complexity level. They hand over the form to the booking officer at the parlor. depending on the availability, the booking officer reserves the time slots and the play station for customers.

Identify the involved classes and objects, and their attributes. Write methods in the class to accept the game details and store the values in a variable.

Exercise 3

Provide the output of the following code:

using System;class Myclass { static void Main(string[] args) { string Answer = "Y"; string Response_code = "66"; int counter = 60; Console.WriteLine(Answer); Console.WriteLine(Response_code); Console.WriteLine(counter); } }

Exercise 4

An automobile company has developed an application for maintaining the number of wheels in a vehicle. Predict the output of the following partial code of the application:

using System;class Vehicle { public int Number_of_tyres; } class MyVehicle { static void Main(string[] args) { Vehicle Motorcycle = new Vehicle(); Vehicle Car = new Vehicle(); Console.WriteLine("Enter the number of vehicles in a car:"); Ca.Number_of_tyres = Convert.ToInt16(Console.ReadLine()); Console.WriteLine("Enter the number of vehicles in a Motorcycle:"); Motorcycle.Number_of_tyres = Convert.ToInt16(Console.ReadLine()); Console.WriteLine("\n"); Console.WriteLine(Car.Number_of_tyres); Console.WriteLine(": is the number of vehicles in a car"); Console.WriteLine(Motorcycle.Number_of_tyres); Console.WriteLine(": is the number of vehicles in a Motorcycle"); } }

Page 25: C#

Exercise 5

Technosoft, a leading software company, has developed application for maintaining the scores of the games in a video parlor. If the new score is greater than the scored top score, the following program should interchange the values of the variables. Top_score and new_score. However, the program does not generate the desired output. Identify the error in the following program and write the correct code.

using System;class Interchange { int Top_score; int New_score; int Temp; void Swap() { Top_score = 5; New_score = 10; Temp = top_score; New_score = Top_score; Top_score = New_score; } void Display() { Console.WriteLine("The new value of the top score is:"); Console.WriteLine(Top_score); Console.WriteLine("The old value of the top score was:"); Console.WriteLine(New_score); } static void Main(string[] args) { Interchange I1; I1.Swap(); I1.Display(); } }

Exercise 6

As a part of the team that is developing software for library, you have been assigned the task of writing a program. The program should accept the following book details

ISBN number Book category (Fiction of non-fiction Author Number of copies available

Write a C# program to accept and display the preceding book details.

Chapter 3

Operators and Programming Constructs

Page 26: C#

Operators are used to compute results and compare the data values of a program. A program often involves decision making and iterative tasks. To accomplish this task, programmers use various operators in the conditional and looping constructs.

This chapter discusses the types of operators used in C# language. In addition, the conditional constructs and the looping constructs are also discussed.

Objectives

In this chapter we will learn to Use various operators

o Arithmetico Arithmetic assignmento Unaryo Comparisono Logical

Use conditional constructs Use looping constructs

Using Operators

Applications use operators to process the data entered by a user. Operators like + and – are used to process variables and return a value. An operator is a set of one or more characters that is used for computations or comparisons. Operators can transform one or more data values, called operands, into a new data value.

Consider the following expression

X + Y

The preceding expression use two operands and an operator to add the values stored in the variables.

Operators in C# can be classified as follows:o Arithmetic operatorso Arithmetic assignment operatorso Unary operatorso Comparison operatorso Logical operators

Arithmetic Operators

These operators are the symbols that are used to perform arithmetic operations on variables. The following table describes the commonly used arithmetic operators.

Operator Description Example+ Used to add 2 numbers X = Y + Z. If Y = 20 and Z= 2,

X will have the value 22.- Used to substract 2 numbers X = Y - Z. If Y = 20 and Z= 2,

X will have the value 18.* Used to multiply 2 numbers X = Y * Z. If Y = 20 and Z= 2,

X will have the value 40./ Used to divide one number by another X = Y / Z. If Y = 21 and Z= 2,

X will have the value 10. But if Y = 21.0 and Z = 2, X will have

Page 27: C#

the value 10.5% Used to divide 2 numbers and return the remainder X = Y % Z. If Y = 21 and Z= 2,

X will have the value 1.

Arithmetic Operators

Arithmetic Assignment Operators

These operators are used to perform arithmetic operations to assign a value to an operand. The simplest of these is “=”. Its general form is VAR = Expression. The following table lists the usage and describes the commonly used arithmetic assignment operators:

Operator Usage Description= X = 5; Stores the value 5 in the variable X+= X+=Y; Same as : X = X + Y-= X-=Y; Same as : X = X - Y*= X*=Y; Same as : X = X * Y/= X/=Y; Same as : X = X / Y%= X%=Y; Same as : X = X % Y

Arithmetic Assignment Operators

Unary Operators

These operators are used to increment or decrement the value of an operand by 1. The following table explains the usage of the increment and decrement operators.

Operator Usage Description Example++ ++ operand ; (pre-increment

operator) or

Operand ++; (post increment operator)

Used to increment the value of an operand by 1

Y = ++X; If the initial value of X is 5, after the execution of the preceding statement values of both X and Y will be 6.Y = X++; If the initial value of X is 5, after the execution of the preceding statement values of X will be 6 and value of Y will be 5

-- -- operand ; (pre-decrement operator) or

Operand --; (post decrement operator

Used to decrement the value of an operand by 1

Y = --X; If the initial value of X is 5, after the execution of the preceding statement values of both X and Y will be 4.Y = X--; If the initial value of X is 5, after the execution of the preceding statement values of X will be 4 and value of Y will be 5

Unary Operators

Page 28: C#

Comparison Operators

These operators are used to compare two values and perform an action on the basis of the result of that comparison. Whenever you see comparison operator, the expression results of Boolean value ‘true’ or ‘false’. The following table explains the usage of commonly used comparison operators.Operator Usage Description Example

(In the following examples, the value of X is assumed to be 20 and value of Y is assumed to be 25)

< Expression1 < expression 2 Used to check whether expression 1 is less than expression 2

bool Result;

Result = X < Y;

Result will have the value true

> Expression1 > expression 2 Used to check whether expression 1 is greater than expression 2

bool Result;

Result = X > Y;

Result will have the value false

<= Expression1 <= expression 2 Used to check whether expression 1 is less than or equal to expression 2

bool Result;

Result = X <= Y;

Result will have the value true

>= Expression1 => expression 2 Used to check whether expression 1 is greater than or equal to expression 2

bool Result;

Result = X >= Y;

Result will have the value false

== Expression1 == expression 2 Used to check whether expression 1 is equal to expression 2

bool Result;

Result = X == Y;

Result will have the value false

!= Expression1 != expression 2 Used to check whether expression 1 is not equal to expression 2

bool Result;

Result = X != Y;

Result will have the value true

Comparison Operators

Logical Operators

Logical operators are used to evaluate expressions and return a Boolean value. The following table explains the usage of logical operators.

Page 29: C#

Operator Usage Description Example&& Expression1 &&

expression 2Returns true if both expression 1 and expression 2 are true

bool Result;string str1, str2;str1 = "Korea";str2 = "France";

Result = (str1 == "Korea") && (str2 == "France"); Console.WriteLine(Result.ToString());

The message displays true because str1 has the value “Korea” and str2 has the value “France”.

! ! expression Returns true if the expression is false

bool Result;int x; x = 20; Result = (!(x ==10)); Console.WriteLine("x is not equal to 10"); The message x is not equal to 10 is displayed because the expression used in the if statement is true

|| Expression1 || expression 2

Returns true if either expression 1 or expression 2 or both of them are true

bool Result;string str1, str2;str1 = "Korea";str2 = "France";

Result = (str1 == "Korea") || (str2 == "France"); Console.WriteLine(Result.ToString());The message displays true if either str1 has the value “Korea” or str2 has the value “France”.

^ Expression1 ^ expression 2

Returns true if either expression 1 or expression 2 is true. Returns false if both expression 1 and expression 2 are true or if both expression 1 and expression 2 are false

bool Result;string str1, str2;str1 = "Korea";str2 = "France";

Result = (str1 == "Korea") ^ (str2 == "France"); Console.WriteLine(Result.ToString());The message displays false because both the expressions are true

Using Conditional Construct

The ability to take decisions is fundamental to human beings. Decision-making can be incorporated into programs as well. This will result in determining the sequence in which a program will execute instructions. You can control the flow of a program by using conditional

Page 30: C#

constructs. Conditional constructs allow the selective execution of statements, depending on the value of the expressions associated with them. The comparison operators are required for evaluating the conditions. The various conditional constructs are:

The if…else construct The switch..case construct

The If…else construct:

The if…else conditional construct is followed by a logical expression, where data is compared and a decision is made on the basis of result of the comparison. The following is the syntax of the if..else construct.

if (expression) { statements; }else { statements; }

The follwing code is an example of if … else constructusing System;

class Leapyear{

public static void Main()

{ int year;

Console.WriteLine("Enter the year:"); year = Convert.ToInt32(Console.ReadLine());

if ((year % 4 == 0) && (year % 100 != 0 || year % 400 == 0))

Console.WriteLine("\n you have entered a Leap Year"); else Console.WriteLine("\n The year you have entered is not a Leap Year");

}

}

The preceding code checks whether the year entered by a user is a leap year. If the condition specifed in the if statement is true, the statements in the if block are executed. And if the condition specifed in the if statement is false, the statements in the else block are executed.

The else part in the if.. else construct is optional and can be omitted as shown in the following code:

int var = 5;if (var>0) Console.WriteLine("Var is a positive number");

Page 31: C#

The if.. else constructs can be nested inside each other. When nested together, the construct is known as cascading if..else constructs. The following code is an example of cascading if..else constructs:

int x, y, z; x = 10; y = 20; z = 30;

if ((x > y) if (x > z))

Console.WriteLine("X is greater than Y and Z"); else

Console.WriteLine("\n Z is greater than X and Y"); else

if (y>z)) Console.WriteLine("\n Y is greater than X and Z"); else Console.WriteLine("\n Z is greater than X and Y");

The preceding code displays the greatest of 3 numbers.

The cascading if..else construct can also be used with logical operators. The following code is an example of converting the cascading if..else construct to an if..else construct by using logical operators:

int x, y, z; x = 10; y = 20; z = 30;

if ((x > y) && (x > z)) Console.WriteLine("X is greater than Y and Z"); if ((y>x) && (y>z)) Console.WriteLine("\n Y is greater than X and Z"); if ((z > x) && (z > y)) Console.WriteLine("\n Z is greater than X and Y");

In the preceding code, the && is used to find the logical and AND of 2 conditions.

The statement Console.WriteLine("X is greater than Y and Z")is executed only if both the conditions evaluate to true.

Note:In case of logical OR operator (||), if the first condition evaluates to true, the second condition is not evaluated.

The Switch..Case construct

Another conditional available in C# is the switch… case construct. It is used when there are multiple values for a variable. The following code is the syntax of the switch case construct:

switch (VariableName) { case Const_Exp1:

Page 32: C#

statements; break; case Const_Exp2: statements; break;

...

.. . case Const_Expn: statements; break; default: statements; break; }

When the switch case statement is executed, the variable given in the switch statement is evaluated and compared with each case constant. If one of the case constants is equal to the value of the variable given in the switch statement, control is passed to the statement following the matched case label. A break statement is used to exit the switch statement. This prevents the execution of the remaining case structures by ending the execution of the switch case construct. Each break statement terminates the enclosing switch statement and the flow of control. If none of the case match, the default case is invoked.

The keyword switch is followed by the variable in parentheses:

switch (var)

Each case keyword is followed by a case constant:

case 1:

The data type of the case constant should match the data type of the switch variable. Before entering the switch construct, a value should be assigned to the switch variable.

You can substitute a complex if..else construct with the switch …case construct. The following code is an example of the complex if..else construct:

int var; var = 500; if (var == 100) Console.WriteLine("Century"); else if (var = 200) Console.WriteLine("Double Century"); else if (var = 300) Console.WriteLine("Triple Century"); else Console.WriteLine("Invalid Value");

The preceding code of the if..else construct can be replaced by a switch..case construct as shown in the following example:

int var; var = 500; switch (var) {

Page 33: C#

case 100: Console.WriteLine("Century"); break; case 200: Console.WriteLine("Double Century"); break; case 300: Console.WriteLine("Triple Century"); break; default: Console.WriteLine("Invalid Value"); break; }

The switch ..case construct evaluates an expression only once at the top of the structure where as the if..else construct evaluates the expression for each if statement.

Note:

The if…else structure can be substituted with a switch….case structure only if each else..if statement in the if…else construct evaluates the same expression.

Activity: Calculator using Conditional constructs

Problem statement

Write a program that emulates a calculator. The calculator should be able to perform the following mathematical operations:

Addition Substraction Multiplication Division

Solution

To develop the required program perform the following steps:1. Select Start All Programs Accessories Notepad2. Write the following program code in Notepad

using System;

class Calculator

{

public static int i = 0;public static int j = 0;

public void AcceptNumbers()

{Console.WriteLine("\n Enter the value of i");i = Convert.ToInt32(Console.ReadLine());Console.WriteLine("\n Enter the value of j");j = Convert.ToInt32(Console.ReadLine());

Page 34: C#

}

public int AddCalc(Calculator c1){

c1.AcceptNumbers();int a1 = i;

int a2 = j; int sum = a1 + a2;

return (sum);

}public int SubCalc(Calculator c1){

c1.AcceptNumbers();int a1 = i;int a2 = j;int difference = a1 - a2;return (difference);

}public int MulCalc(Calculator c1){

c1.AcceptNumbers();int a1 = i;int a2 = j;int multi = a1 * a2;return (multi);

}public float DivCalc(Calculator c1){

c1.AcceptNumbers();int a1 = i;int a2 = j;float div = a1/a2;return (div);

}public static void Main()

{Calculator c = new Calculator();Calculator g = new Calculator();

Console.WriteLine("\n\b\bPlease enter the required option \n 1. Addition \n 2. Substraction \n3.Multiplication \n4.Division");

int h=0;h=Convert.ToInt32(Console.ReadLine());

switch (h) { case 1: int s1 = c.AddCalc(g); Console.WriteLine("\n The value of the addition is {0}", s1); break;

Page 35: C#

case 2: int s2 = c.SubCalc(g); Console.WriteLine("\n The value of the substraction is {0}", s2); break; case 3: int s3 = c.MulCalc(g); Console.WriteLine("\n The value of the multiplication is {0}", s3); break; case 4: float s4 = c.DivCalc(g); Console.WriteLine("\n The value of the Division is {0}", s4); break; }

}}3. Select File Save to save the program file. The Save As dialog box opens4. Enter Calculator.cs in the File name text box. The filename is saved with the .cs

extension, signifying that it is a C# program.5. click the Save button in the Save As dialog box6. Select Start all programsVisual studio 2005Visual studio Tools Visual

studio 2005 command prompt to compile this program7. In the Visual studio 2005 Command Prompt window, move to the location where the

program file is saved8. Compile the program file by using the following command

csc Calculator.cs9. To execute the code, type the following on the command prompt:

Calculator.exe10. Verify the output of the executed program

Using Loop Constructs

Loop constructs are used to execute one or more lines of code repetitively. The following loop construts re supported by C#:

The while loop The do..while loop The for loop

The while loop

The while loop construct is used to execute a block of statements for a definite number of times, depending on a condition. The while statement always checks the condition before executing the statements within the loop. When the execution reaches the last statement in the while loop, the control is passed back to the begening of the loop. If the condition still holds true, the statements within the loop are executed again. The execution of the statements within the loop continues until the condition evaluates to false.

The following code is the syntax of the while loop construct:

While (expression){Statements;}

Page 36: C#

The following code is an example of the while loop construct:

using System;class Variable { static void Main(string[] args) { int var; var = 100; while (var < 200) { Console.WriteLine("Value of Variable is {0}", var); var = var + 10; Console.ReadLine(); } }

}

The preceding code creates an integer vriable var and assigns the value 100 to it. The while statement checks whether the value of var is lower than 200. If the condition evaluates the true, the statements within the while loop are executed. This process continues until the value of var becomes greater than or equal to 200.

You can use the break statement to to exit the while loop structure. The following code is an example of the break statement

int var; var = 100; while (true) { Console.WriteLine("Value of Var: ",+ var); var = var + 10; if (var >= 200) break; }In the preceeding code, the while statement while(true) will always evaluate to true and the while block will run an indefinite number of times. In such a case, the break statement is used to exit the while loop block on the basis of the condition given within the while block. In the preceeding example, the control moves out of the while loop when the value of var becomes greater than or equal to 200.

The do…while loop

The do..while loop construct is similar to the while loop construct. Both iterate until the specified loop condition becomes false. However, in the do..while loop, the body of the loop is executed atleast once and the condition is evluated for subsequent interactions.

The following code is the syntax of the do..while loop construct:

Do{Statements;

Page 37: C#

}while(expression);

Consider the following example of the do.while loop construct:

int var;Var = 100;do{ Console.writeLine(“Value of var: “ + var); Var = var + 10;}While (var < 200);

In the preceding code, the condition is checked after the statements in the do..while loop sructure is executed. Therefore, the statements within the do…while loop are executed at least once, regardless of whether the condition evaluates to true or false.

Page 38: C#

The difference between the do..while and while loop constructs is shown in the following figure.

Difference in Execution of the do..while and whileloop

The for loop

The for loop structure is used to execute a block of statements for a specific number of times. The following code is the syntax of the for loop construct:

For (initialization; termination ; increment/decrement){ Statements}

The initialization expression initializes the for loop construct. It is executed once at the begenning of the loop. The termination expression determines when to terminate the loop. At the begening of the loop, this expression is evaluated for each interation. When the expression evaluates to false, the loop terminates. Then, through the loop, the increment or decrement expression gets invoked after each iteration. All these components are optional.

You can create an infinite loop by omitting all the three expressions, as shown in the following code:

For ( ; ; ){ . . .}

Execute Body of the Loop

Evaluate Condition

Execute Body of the Loop

Evaluate Condition

True

False

Do while

True

False

while

Page 39: C#

The sequence of the execution of a complete for loop construct is shown in the following figure

Sequence of execution for the loop.

The following is an example of the for loop strcture that displays integers between 10 and 20:

using System;class Variable { static void Main(string[] args) { int var; for (var = 10; var <= 20; var++) { Console.WriteLine("Value of the variable is:{0}", var); Console.ReadLine(); } } }Activity: Fibonacci Series Using Loop Constructs

Problem statement

Write a program that generates the Fibonacci series up to 200.

Solution

To create the required program, perform the following steps:

1. Select Start All Programs Accessories Notepad

Initialization

Evaluate Condition

Body of the Loop

Increment/Decrement

Exit the For Loop

True

False

Page 40: C#

2. Write the following program code in Notepad

using System;

class Fibnossi{

public static void Main()

{int n1 = 1;int n2 = 1;

Console.WriteLine(n1);

while (n2<200){

Console.WriteLine(n2);n2 = n2+ n1;n1 = n2 - n1;

}}

} 3. Select File Save to save the program file. The Save As dialog box opens4. Enter Fibonacci.cs in the File name text box. The filename is saved with the .cs extension, signifying that it is a C# program.5. Click the Save button in the Save As dialog box6. Select Start all programsVisual studio 2005Visual studio Tools Visual

studio 2005 command prompt to open the visual studio 2005 command prompt window7. In the Visual studio 2005 Command Prompt window, move to the location where the program file is saved8. Compile the program file by using the following commandcsc Fibonacci.cs9. Execute the compiled program as :Fibonacci.exe10. Verify the output of the executed program

The break and continue Statements

At times, there is a need to exit a loop before the loop condition is re-evaluated after iteration. As with a while loop, you can use the break statement to exit for loop. The continue statement is used to skip all the subsequent instructions and take the control back to the loop.

The following code accpets five numbers and prints the sum of all the positive numbers:

using System;

class BreakContinue { static void Main(string[] args) { int incr, SumNum, number; for (SumNum = number = incr = 0; incr < 5; incr += 1) { Console.WriteLine("Enter a Positive Number");

Page 41: C#

number = Convert.ToInt32(Console.ReadLine());

if (number <= 0) //Non-positive numbers continue; //Continue to incr+=1 in the for loop SumNum = SumNum + number; } Console.WriteLine("The sum of the positive numbers entered is {0}", SumNum);

Console.ReadLine(); } }

Practice Questions

1. Consider the following code:

static void Main(string[] args) { char character; Console.WriteLine("Enter a Character:"); character = Convert.ToChar(Console.ReadLine());

if (character == 'X') Console.WriteLine("The Character is X"); else Console.WriteLine("The character is not X); Console.ReadLine();

}

Note

The convert.ToChar( ) converts a value to the char datatype

What will be the output if the input of the preceding code is x?

a. The character is xb. The character is not xc. Error messaged. x

2. To which category of operators do the ++ belong?

a. Arithmetic operatorsb. Arithmetic assignment operatorsc. Unary operatorsd. Comparision operators

3. Which of the following operators can be used to evaluate an expression to ture only if both the conditions are true?

a. &&b. | |c. >=d. ! =

4. State whether the following statement is True or False:

Page 42: C#

The continue statement if used in the while and do…while loop caues the program control pass to the top of the loop avoiding the other statements in the loop.

5. State whether the following statement is true or False:

A termination expression is evaluated at each iteration of the for loop.

Summary

In this chapter, you learned that:

Operators are used to compute and compare values and test multiple conditions. You use arithmetic operators to perform arithmetic operations on variables like addition,

substraction, multiplication, and division You can use arithmetic assignment operators to perform arithmeic operations and assign

the result to a variable. The unary operators, such as the increment and decrement operators, operate on one

operand Comparision operators are used to compare two values and perform an action on the

basis of the result of the comparison Logical operators are used to compare two valuse and return a Boolean value. Conditional constructs are used to allow the selective execution of statements. The

conditional constructs in C # are:o If ..elseo Switch..case

Looping constructs are used when you want a section of a program to be repeated a certain number of times. C# offers the following looping constructs

o Whileo Do …whileo For

The break and continue statements are used to control the program flow within a loop.

Exercises

Exercise 1

Write a program to identify whether a character entered by user is a vowel or a consonant

Exercise 2

Write a program to identify whether the number entered by a user is even or odd.

Exercise 3

Write a program to accept a number from the user and display all the prime numbers from zero up to the number entered by user.

Page 43: C#

ENCAPSULATION AND ABSTRACTIONChapter-4

Objects contain data and methods to end and receive messages.Data memebers of objects can have a different scope or visibility. You use access specifier to define the scope of data member and method.

This chapter introduces the concept of abstraction and encapsulation. It discusses the implementation and encapsulation by using access specifiers. It also explains the concept of using methods. In addition, the chapter also discusses the static variables and static function.

Objectives

In this chapter, you will learn to:

Define abstrction and encapsulation Implement encapsulation by using access specifiers Use methods Use static variables and static functions

Introducing Abstraction and Encapsulation

Abstraction and encapsulation are importnt features of any OOP language. Abstraction involves only the relavant information. Encapsulation involves in packaging one or more components together.

Defining Abstraction

Consider the following example:

An automobile salesperon is aware that different people have different performances. Some people are interested in the spedd of the car, some in its price,some in the engine and some in the style. Although all of them want to buy a car,each of them is interested in a specific attribute or feature. The sales man knows all the details of a car, but he presents only the relevant information to a potential customer. As a result, the salesman practices abstraction and presents only relavent details to customer.

In other words, abstraction means ‘looking for what you want’ in an object or a class.

Consider the abstraction from the perspective of a programmer who wants a user to be able to add items to a list. Howevr, the details of how a particular task in a program is accomplished is hidden. Anstraction does not mean that information is unavailable. It means that all the information exists, but only the relevant information is provided to the user.

Defining Encapsulation

Encapsulation literally means ‘to enclose in or as if in a capsule.’ Encapsulation is defined as the process of enclosing one or more items within a physical or logical package. It involves preventing access to nonessential details.

For example, when you plug in the cord of the vaccum cleaner and turn on the switch, the vaccum cleaner starts. You do not see the complex processes needed actually to convert electricity into suction power. In the otherwords, the exact working of the cleaner has been encapsulated. Therefore, encapsulation is also explained as information hiding or data hiding because it involves hiding many of the important details of an object from the user.

Page 44: C#

Abstraction ad encapsulation are different but related features. Abstraction enables yo to kae the relavent information visible. Encapsulation enables you to package information to implement the desired level of abstraction. Therefore, encapsulation assists abstraction by providing a means of suppressing the nonessential details. Encpsulation allows som information to be hidden but it also allows some information to be hidden but it also allows some information to be visible.

Implementation Encapsulation by Using Access Specifiers

An access specifier defines the scope of a class member. A class member refers to the variables and functions in a class. A program can have one or more classes. You may want some members of a class to be accessible to the other classes. But, you may not want some other members of the class to be accessible outside the class.

It is the privilage of the programmer to decide the use of access specifiers to iplement encapsulation and abstraction in C#.

Consider the world of modern advertising. Viewers are bombarded with hundreds of advertising messages everyday. If they were to listen to, understand and respond to all of them, they would probably not have much time and energy left for anythin else. Instead, they concentrate only on messages that are of specific intrest to them. Thus, for example if they want to buy a rerigerator, they will pay attention to the advertisements that feature refrigerators.

Similarly, a housewife would typically pay attention to the size, ese of handling, and durability of a vaccum cleaner. She would not be interested in the gadgetry inside it, which is in the purview of the maintenance man. Sales personnel may concentrate on entirely different factors. There is a term given to the preceeding process: Abstraction

You use various types of access specifiers to specify the extent of the visibility of the class member.

Types of Access Specifers

C# supports the following access specifiers: Public Private Protected Internal protected internal

The public Access Specifier

The public access specifier allows a class to expose its member variables and member functions to other functions and objects. Any member that is declared public can be accessed from outside the class.

The following is an example of the use of the public access specifier:

using System;class car { private string CarColor; //since the variable is private // it cannot be accessed outside the class definition } class Bike {

Page 45: C#

public string BikeColor; //Since the variable is public // it can be accesses outside the class definition. } class Result { static void Main(string[] args) { car Ford = new car(); Bike Honda = new Bike(); /* The . operator is used to access the member data and functions */

Ford.CarColor = "red"; /* Error! Cannot access the private members */

Honda.BikeColor = "blue"; Console.ReadLine(); } }

In the preceeding example, the CarColor variable cannot be accessed from any function outside the car class. On the other hand, the BikeColor variable is a public member. Therefore, it can be accessed from outside the class.

The following is another exaple of the use of the public specifier:

using System; class car { private string Color; public void Honk() { Console.WriteLine("BEEP BEEP!"); } }class Result { static void Main(string[] args) { car Ford = new car(); Ford.Honk() // Displays BEEP BEEP! Console.ReadLine(); } }

In the preceeding example, the Honk()function will be accessible from anywhere in the program and can be accessed by using the objects of the car class.

The Private Access Specifier

The private access specifier allows a class to hide its member variables and member functions from other class objects and functions. Therefore, the private member of a class is not visible outside a class. If a member is declared private, only the unctions of that clas can access the member. Even the instance of the class cannot access its private members. Therefore, the data is hidden and cannot be altered by any function other than the member functions of the class.

Page 46: C#

The following is an example of the use of private access specifier:

using System;class car { private string Model; void Honk() { Console.WriteLine("PARRP PARRP!"); } public void SetModel() { Console.WriteLine("Enter the Model Name:"); Model = Console.ReadLine(); } public void DisplayModel() { Console.WriteLine("The model is:{0)", Model); }

}class Display { static void Main(string[] args) { car Ford = new car(); Ford.SetModel(); //Accepts the Model Name Ford.DisplayModel(); //Displays the Model Name Ford.Honk(); // Error! Private members cannot be accessed outside the class definition return 0; } }

In the preceeding example, the SetModel()and DisplayModel()functions cn be called from the Ford object, created in the Main( ) function because these are public member functions. Similarly, the Honk( ) function cannot be accessed through the Ford object because it is a private member function.

When you do not specify any data member as public, protected, or private, then the default access specifier for a data member is private. In the following example, the data member Model is private, even though it has not been specified explicitly:

class car { char Model; . . . . }

Page 47: C#

The protected Access Specifier

This specifier allows a class to hide its member variabls and member functions from other class objects and functions, except the child class. The protected access specifier becomes important while implementing inheritence.

The follwong example shows the protected member of the class will have the same visibility asa private member of the class

using System; class car { protected string Model; void Honk() { Console.WriteLine("PARRP PARRP!"); } public void SetModel() { Console.WriteLine("Enter the Model Name:"); Model = Console.ReadLine(); } public void DisplayModel() { Console.WriteLine("The model is:{0)", Model); }

}class Display { static void Main(string[] args) { car Ford = new car(); Ford.SetModel(); //Accepts the Model Name Ford.DisplayModel(); //Displays the Model Name Ford.Honk(); // Error! Private members cannot be accessed outside the class definition Console.WriteLine(Ford.Model); //Error! protected members cannot be accessed return 0; } }

In the preceding example, the SetModel( ) and DisplayModel( ) functions can be called from the Ford object defined in the Mian( ) function. However, the Model variable cannot be accessed through the Ford object because it is a protected member variable. Similarly, The Honk( ) function cannot be accessed through the Ford object because it is also a private member function.

The Internal Access specifier

The internal access specifier allows a class to expose its member variables and member functions to the other functions and objects. Any member that is declared internal can beaccessed from any class or method defined within the application in which the member is defined. Whn you do not specify any data member as public, protected, or private the default access specifier for a class is internal.

Page 48: C#

The following is an example of the use of the internal access specifier:

using System;class car { private string CarColor; //Since the variable is private // it cannot be accesses outside the class definition. internal void Honk() { Console.WriteLine("BEEP BEEP!"); } } class Bike { internal string BikeColor; //Since the variable is internal // it can be accesses outside the class definition. } class Result { static void Main(string[] args) { car Ford = new car(); Bike Honda = new Bike(); Ford.CarColor = "red"; /* Error! Cannot access the private members */

Honda.BikeColor = "blue"; Ford.Honk() // Displays BEEP BEEP! Console.ReadLine();

} }

In the preceding example, the carColor variable cannot be accessed from any function outside the Car class. On the other hand, the BikeColor variable is an internal member. Hence, it can be accessed from outside the class. Also, the Honk( ) function will be accessible from anywhere in the program and can be accessed by using the objects of the Car class.

The Protected Internal Access Specifier

This specifier allows a class to hide its member variables and member functions to be accessed from other class objects and functions, except the child class, within the application. The protected internal access specifier becomes important while implementation inheritance.

The following example shows that the protected internal memberof the class will have the same visibility as a private member of the class:

using System; class car { protected internal string Model; void Honk() { Console.WriteLine("PARRP PARRP!");

Page 49: C#

} public void SetModel() { Console.WriteLine("Enter the Model Name:"); Model = Console.ReadLine(); } public void DisplayModel() { Console.WriteLine("The model is:{0)", Model); }

}class Display { static void Main(string[] args) { car Ford = new car(); Ford.SetModel(); //Accepts the Model Name Ford.DisplayModel(); //Displays the Model Name Ford.Honk(); // Error! Private members cannot be accessed outside the class definition Console.WriteLine(Ford.Model); //Error! protected internal members cannot be accessed outside the class definition return 0; } }

In the preceding example, the SetMode ( ) and dDisplayMode ( ) functions can be called from the Ford object defined in the Main ( ) function. However, the model variable cannot be accessed through the Ford objects because it is a protected internal member variable. Similarly, the Honk () function cannot be accessed through the Ford object because it is also a private member function.

The following table shows the visisbility of the class members for the access specifiers

Access Specifiers

Visible to own class members

Visible to objects of other class

Visible to objects of other class outside the namespace collection

Visible to objects of child classes outside the namespace collection

Public Yes Yes Yes YesPrivate Yes No No NoProtected Yes No No YesInternal Yes Yes No NoProtected internal

Yes No No No

Visibility of class members

Activity: Calculating Area and Volume by Using Access specifiers

Problem Statement

Write a program to calculate the area of a rectangle and a square.

Solution

Page 50: C#

To develop the required program perform the following steps:

1. Select Start All Programs Accessories Notepad2. Write the following program code in Notepad

using System;

class Area{

static int result; public void RecArea()

{int l;int w;

Console.WriteLine("\n Enter the length of the rectangle:");l = Convert.ToInt32(Console.ReadLine());Console.WriteLine("\n Enter the width of the rectangle:");w = Convert.ToInt32(Console.ReadLine());

result = l * w;Console.WriteLine("\n The area of the rectangle is :{0}",

result);

}

public void SqArea(){

int s;Console.WriteLine("\n Enter the side of the Square:");s = Convert.ToInt32(Console.ReadLine());

result = s*s;Console.WriteLine("\n The area of the Square is :{0}",

result);

}

static void Main(){

Area a = new Area();int c;

Console.WriteLine("\n Main Menu");Console.WriteLine("\n 1. Area of Rectangle");Console.WriteLine("\n 2. Area of Square");Console.WriteLine("\n Choose 1 or 2");c = Convert.ToInt32(Console.ReadLine());

switch (c)

{

case 1:

Page 51: C#

a.RecArea();break;

case 2:a.SqArea();break;

default:break;

}}

}

3. Select File Save to save the program file. The Save As dialog box opens4. Enter Area.cs in the File name text box. The filename is saved with the .cs extension, signifying that it is a C# program.5. Click the Save button in the Save As dialog box7. Select Start all programsVisual studio 2005Visual studio Tools Visual

studio 2005 command prompt to open the visual studio 2005 command prompt window7. In the Visual studio 2005 Command Prompt window, move to the location where the program file is saved8. Compile the program file by using the following commandCsc Area.cs9. Execute the compiled program as :area.exe10. Verify the output of the executed program

Using methods

A method is a set of one or more program statements, which can be executed by refering to the method name.

Method play a key role in modular programming. When a complex application is divided into methods, code is more flexible and easy to maintain and to debug. Methods are useful for performing repetitive tasks, such a fetching specific records and text. They allow you to break an application into discrete logical units, whuch makes the application more readable. You can reuse code written in a method because it can be executed any number of times by calling the method with little or no modification.

To use methods, you need to: Define methods Call methods

Defining methods

Defining a method means declaring the elements of its structure. Consider the syntax of defing a method:

< Access specifier > <Return Type> <Method Name>(Parameter list){ Mehod body}

Page 52: C#

The elements of the method declaration include the method name, the parameters list, the return type, and the method body. The following are the elements of a method:

Access specifier: This determines the extent to which a variable or method can be accessed from another class

Return type: A method can return a value of any type. If the method is not returning any value, use void as the return type.

Method name: This is unique identifier and is case-sensitive. The method name cannot be the same as the variable name or any other non-method item declared in the class.

Parameter list: This is used to pass and receive the data from a method. It is enclosed between parentheses. The parameters are included even if there are no parameters.

Method Body: This contains the set of instructions needed to complete the required activity.

Consider the following code snippet of method definiton:

class Calculator

{public int AddNumber(int num1, int num2)

{ int result; result = num1 + num2; return result;

}}

In the preceding code snippet, the public access specifier states that the method can be accessed from outside the class. The method is returning the integer value as specified in the method declaration. AddNumber is the name of the method. It is good practice to specify the method name in Pascal Case. The method is taking two integers as the parameters and retuning the value stored I result variable.

Calling methods

After defining the method, you can tell it by using the name of the method. The method name is followed by parentheses even if the method call has no parameters, as shown in the following example:

MethodName ( );

The following is an example of calling methods:

using System;class Calculator { public int AddNumber(int num1, int num2) { int result; result = num1 + num2; return result; } static void Main(string[] args) { Calculator cal = new Calculator(); // The following statement is calling the AddNumber method and

Page 53: C#

// passing 10 and 20 as the parameter list

int value = cal.AddNumber(10, 20); Console.WriteLine("The result is {0}", value); Console.ReadLine();

} }

The preceding example begins at the start of the Main() method of the Calculator class. An object named cal is created to access the method of the class. When you call the method AddNumber (int num1, int num2), pass two integer values AddNumber(10, 20) to the method. This method returns an integer value, which is stored in the variable, value.

Since the return type of Main( ) is void, the return statement is not returning any value. The return statement is used to make a method return immediately to the caller. Without a return statement, the execution returns to the caller by default when the last statementin the method is reached. This type of return is called an immediate return.

You can also call public methods from other classes by using the object of the class. The following example shows how to call the method of Calculator class from Test class:

using System;class Calculator { public int AddNumber(int num1, int num2) { int result; result = num1 + num2; return result; } } class Test { static void Main(string[] args) { // Creating an object of a class Calculator Calculator cal = new Calculator(); // Calling the method AddNumber(10,20)of the class Calculator

int value = cal.AddNumber(10, 20); Console.WriteLine("The result is {0}", value); Console.ReadLine();

} }

A method can call itself. This is known as recursion.

The following is an example of the recursive method:

using System;class Number {

Page 54: C#

public int Factorial(int n) { int result; if (n == 1) return 1; else{ { result = Factorial(n-1) *n; return result; } } static void Main(string[] args) { Number obj = new Number(); Console.WriteLine("Factorial of 3 is:"); obj.Factorial(3); Console.WriteLine("Factorial of 4 is:"); obj.Factorial(4); Console.WriteLine("Factorial of 5 is:"); obj.Factorial(5); Console.ReadLine(); } }In the preceding code, the factorial ( ) method is recursive method. If the value entered by the user is not 1, this method will call itself.

Using methods with parameters

As discussed earlier, parameters allow information to be passed in and out of method. When you define a method, you can include a list of parameters in parentheses.

Declaring methods with Parameters

Each parameter has a type and name. You can declare parameters by placing parameter declarations inside parentheses. A syntax that is used to declare parameters is similar to the syntax that is used to declare local variables. However, you can separate each parameter declaration with a comma.

The following example shows how to declare a methos with parameters:

Void MethodWithParameters(int n, string y){ // …..}

The preceding code declares the method MethodWithParameters with two parameters n and y. the first parameter is of type int, and the second parameter is of type string.

Calling methods with parameters

When a method with parameters is called, you must pass the parameters to the method. Parameters can be passed by using any one of the following mechanism:

Value: Aresometimes called in parameters, therefore, the data can be transferred into the method but cannot be transferred out.

Page 55: C#

Reference: Are sometimes called in/out parameters, therefore, the data can be transferred into the method and out again.

Output: Are sometimes called out parameters, therfore, data can be transferred out of the method.

Pass parameter by value:

Pass by value is defalut mechanism for passing parameters to a method. The simplest defenition of a value parameter is a data type name followed by a variable name. when a method is called, a new storage location is created for each value parameter. The values of the corresponding expressions are copied into them. The expression supplied for each value parameter must be similar to the declaration of the value parameter. Or it must be a type that can be implicity converted to the value type. The syntax of declaring value parameter is as follows:

<return type> MethodName(<data type> variableName){ \\\ ….}

Within the method, you can write code that changes the value of the parameter. A parameter will have no effect any variables outside the method call.

In the following example, the variable var inside AddOne() method separate from the variable number in the Main() method and it can be changed in AddOne(), wihtout effecting var:

using System;class Calculator { void AddOne(int var) { var++; } static void Main(string[] args) { Calculator obj = new Calculator(); int number = 6; obj.AddOne(number); Console.WriteLine(number); //Display the value of 6 not 7 } }

The graphical representation of the memory allocated to the variables is shown in the following figure:

Page 56: C#

Pass Parameter by Reference

Memory allocated to value type parameters

Pass Parameter by Reference

A reference parameter is a reference to a memory location of a data member. Unlike a value parameter, a reference parameter does not create a new storage location. Instead, a reference parameter represents the same location in memory as the variable that is supplied in the method call.

You can declare a reference parameter by using the ref keyword before the data types, as shown in the following example:

void ShowReference(ref nId, ref long nCount) { // .... }

The ref keyword only applies to the parameter following it and not to the whole parameter list. Consider the following method, in which nId is passed by reference but longVar is passed by value:

void OneRefOneVal(ref nId, long longVar) { // .... }

When calling the method, you supply reference parameters by using the ref keyword, which is followed by a variable name. The value supplied in the call to the method must exactly match the type in the method definition. And, it must be a variable, not a constant or a calculated expression.

The following is an example of calling a method with reference type parameters:

6number

var

6

var

7

Main()

AddOne()AddOne()

Before Method Call After Method Call

Page 57: C#

class Calculator { void AddOne(ref int var) { var++; } static void Main(string[] args) { Calculator obj = new Calculator(); int number = 6; obj.AddOne(ref number); Console.WriteLine(number); //Display the value 7 } }

The graphical representation of the memory allocated to the variables of the preceding code is shown in the following figure:

If you omit the ref keyword or if you supply a constant or a calculated expression, the compiler will reject the call. You will receive an error message that is similar to the message: “Cannot convert from ‘int’ to ‘ref int’”.

Pass parameter by Output

As discussed earlier, to return a value from a method you can use the return statement. A return statement can be used to return only a single value. This limitation is overcame by the output parameter.

number number

var var

6 7

*** ***

Main() Main()

AddOne() AddOne()

At the method call After execution of var++ statement

Page 58: C#

Output parameters are like reference parameters, except that they transfer data out of the method rather than into it. An output parameter is a reference to a storage location supplied by the caller. However, the variable that is supplied for the output parameter does not need to be assigned a value before the call is made, and the method will assume that the parameter has not been initialized on entry.

Output parameters are useful when you want to return values from a method by means of a parameter without assigning an initial value to the parameter. To declare an output parameter, use the keyword out before the data type and the variable name.

The following is an example of output parameters:

static void OutDemo(out int variable) { // ... }

The out keyword only affects one parameter, and each output parameter must be marked separately. When calling a method with an output parameter, place the out keyword before the variable to be passed, as shown in the following example:

int var;OutDemo(out var);

In the body of the method being called, no initial assumptions about the contents of the output parameter are made. It is treated like an unassigned local variable. The output parameter must be assigned a value inside the method.

Activity: Swapping Two Numbers by Using Methods with Parameters

Problem Statement

Write a program to swap two numbers by using reference type parameters in the method.

Solution

To write the required program, perform the following steps:

1. Select Start All Programs Accessories Notepad2. Write the following program code in Notepad

using System;using System.Collections.Generic;using System.Text;

public class SwapNumber{ void SwapNum(ref int a, ref int b) { int temp; temp = a; a = b; b = temp; } static void Main(string[] args)

Page 59: C#

{ SwapNumber classobj = new SwapNumber(); int number1, number2; Console.WriteLine("Enter the first number:"); number1 = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Enter the second number:"); number2 = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("The value of the first number is {0}", number1); Console.WriteLine("The value of the second number is {0}", number2);

classobj.SwapNum(ref number1, ref number2); Console.WriteLine("Now the value of the first number after swapping is {0}", number1); Console.WriteLine("Now the value of the second number after swapping is {0} ", number2); Console.ReadLine();

}}3. Select File Save to save the program file. The Save As dialog box opens4. Enter SwapNumber.cs in the File name text box. The filename is saved with the .cs extension, signifying that it is a C# program.5. Click the Save button in the Save As dialog box8. Select Start all programsVisual studio 2005Visual studio Tools Visual

studio 2005 command prompt to open the visual studio 2005 command prompt window7. In the Visual studio 2005 Command Prompt window, move to the location where the program file is saved8. Compile the program file by using the following commandCsc SwapNumber.cs9. Execute the compiled program as :SwapNumber.exe10. Verify the output of the executed program

Using Static Variables and Static Functions

Each object has its own set of member variables. All the member variables have a scope. For example, if you create the temp integer variable inside a function, the variable will be destroyed when the function execution completes. In other words, every time the function is called, temp will be created, initialized, and then destroyed when the function exists. If you want a variable to retain its value throughout the program, you can declare it as a static variable in the program. To manipulate and use the values of static variables, you can also define a function as static.

Static Variables

The keyword ‘static’ means that only one instance of a given variable exists for a class. Static variables are used to define constants because their values can be retrieved by invoking the class without creating an instance of it.

Static variables can be initialized outside the member function or class definition. The following code is an example of static variables, which shows the declaration and initialization of a static variable. Consider the following example of static variables:

using System;

Page 60: C#

class Program { static void Main(string[] args) { StaticExample.ivar = 1; //static variable initialized Console.WriteLine(StaticExample.ivar.ToString()); Console.ReadLine(); } } public class StaticExample { public static int ivar; //static variable declared StaticExample() { Console.WriteLine("Object Created"); } }

In the preceding code, a static variable is initialized outside the class definition. Creating more than one object will not reinitialize the static variable. Unlike other member variables, only one copy of the static variable exists in the memory for all the objects of that class. Therefore, all objects share one copy of the static variable in the memory.

Consider a situation where you are required to track the number of objects created for a class. If you declare a non-static member variable called counter, every instance of the class will create a separate variable. And there will be no variable with a count of the total number of created objects. To avoid such a situation you can use static member variables because the single static variable gets incremented by all objects.

You can also initialize the static variable inside the class definition, as shown in the following example of static variables:

using System;class Static { static void Main(string[] args) { StaticExample s1 = new StaticExample(); StaticExample s2 = new StaticExample(); s1.count(); s1.count(); s1.count(); Console.WriteLine("The value of variable is {0}", s2.display()); Console.ReadLine(); return 0; } } public class StaticExample { public static int s; public void count() { s++; }

Page 61: C#

public int display() { return s; } }

Avani’s Note : Return 0 in the main function throws an error. If that statement is commented then the rest of the program returns the desired output.

Static Functions

You can declare a static function. Such functions can access only static variables. In a situation where you want to check whether an object of a class has been created, you make use of static functions because they exist even before the object is created.

The following is the example of static functions:

Activity: Counting the Number of Times Function is Called by Using Static Functions:

Problem Statement

Solution

To write the required program, perform the following steps:

1. Select Start All Programs Accessories Notepad

using System;class Static { static void Main(string[] args) { StaticExample s = new StaticExample(); s.count(); s.count(); s.count(); Console.WriteLine("The value of variable is {0}", StaticExample.display()); Console.ReadLine(); //return 0; } } public class StaticExample { public static int s; public void count() { s++; } public static int display() { return s; } }

Page 62: C#

2. Write the following program code in Notepad

3. Select File Save to save the program file. The Save As dialog box opens4. Enter FunctionCount.cs in the File name text box. The filename is saved with the .cs extension, signifying that it is a C# program.5. Click the Save button in the Save As dialog box9. Select Start all programsVisual studio 2005Visual studio Tools Visual

studio 2005 command prompt to open the visual studio 2005 command prompt window7. In the Visual studio 2005 Command Prompt window, move to the location where the program file is saved8. Compile the program file by using the following commandCsc FunctionCount.cs9. Execute the compiled program as :FunctionCount.exe10. Verify the output of the executed program

Practice Questions

1. State whether the given statement is true or falseEncapsulation means preventing access to nonessential data

2. Consider the following statementsStatement A: Static variables retain their values even after the function to which they belong have been executed

Statement B: Static functions can access static as well as non-static variablesWhich of the given statements are true

a) A and B both are trueb) A is true and B is falsec) A is false and B is trued) A and B both are false

3. Which of the following statement about access specifiers is true?

using System;public class FunctionCount { public static int count = 0; public static void CountFunction() { count++; System.Console.WriteLine("Count function is called by Main {0} times", count); } static void Main(string[] args) { for (int var = 0; var < 10; var++) { FunctionCount.CountFunction(); } Console.ReadLine(); } }

Page 63: C#

a. An access specifier determines which feature of a class can be used by other classesb. Protected variables are not accessible to the subclasses of the class in which they are

declaredc. A method declared as public in a superclass cannot be accessed by the subclasses of that

superclassd. A variable declared inside a method can have access specifiers

4. State whether the following statement is true or falseIn a public access specifier, all the public members of the base class become protected

5. State whether the given statement is True of False:Abstraction represents the essential characteristics of an object or classes that differentiate it from other objects or classes

Summary

In this chapter, you learned that: Abstraction is the process of reducing information content in order to retain only the

relevant information for a particular purpose Encapsulation is the process of hiding all the details of an object that do not contribute to

it essential characteristics An access specifier is used to determine whether any other class or function can access

the member variables and functions of a particular class The public access specifier allows a class to expose its member variables and member

functions to other functions and objects The private access specifier allows a class to hide its member variables and member

functions from other class functions and objects The protected access specifier allows a class to hide its member variables and member

functions from other class functions and objects, just like the private access specifier while implementing inheritance

A method is a set of one or more program statements that can be executed by referring to the method name

Defining a method means declaring the elements of its structure The access modifiers that can used with methods are public, protected, internal,

protected internal and private Parameters allow information to be passed into and out of a method. When you define a

method, you can include a list of parameters in parenthesis Parameters can be passed by using any one of the following parameter types:

o Valueo Referenceo Output

Pass by value is the default mechanism for passing parameters in C#. A reference parameter is a reference to a memory location of a data member Output parameters are like reference parameters, except that they transfer data out of

the method rather than into it The return statement is used to make a method return immediately to the caller The static variable retains its value even after the function to which it belongs has been

executed The static functions can access only static variables. Non-static variables cannot be

accessed by using static functions

Page 64: C#

Exercises

Exercise 1

Write a program that emulates a calculator. The calculator should consist of the following methods:

Addition Subtraction Multiplication Division

Each method should have a minimum of two parameters

Exercise 2

Write a program to identify the greatest of three numbers entered by a user. Create this program by using methods

Exercise 3

Write a program to calculate the factorial of the number entered by a user. Create this program by using static functions and static variables.

Hint: The limit of users input should be 1-20.

Exercise 4

Information Technologies is a software development organization. Annie a software developer of the organization is currently under a project of cineplexes. She has to develop a program that a program that counts the number of tickets sold. If a ticket is not sold, the program should give the following message “You should sell the tickets”.

Page 65: C#

Chapter 5

Creating Value Types and Reference Types

The variables in a program are allocated memory at run time in the system. In C#, variables are referred in two ways, value type and reference type. Value type variables contain data, whereas reference type variables hold the reference to the memory location where data is stored.

This chapter explains how C# manages memory for its data type variables. It also explains the implementation of value types such as structure and enumeration. This chapter describes how to implement reference types such as arrays and collections in C#.

Objectives

In this chapter, you will learn to Describe memory allocation Use structures Use enumerations Implement arrays Use collections

Describing Memory Allocation

The memory allocated to variables is referred to in two ways, value types and reference types. All the built-in data types such as int, char, and float are value types. When you declare an int variable, the compiler generates code that allocates a block of memory to hold an integer.

int Num1 = 50;

The preceding statement assigns a value to the int type variable Num1 and the value is copied to the memory.

Reference types, such as classes are handled differently by the compiler. When you declare a class variable the compiler does not generate code that allocates a block of memory to hold a class. Instead it allocates a piece of memory that can potentially hold the reference to another block of memory containing the class. The memory for the class object is allocated when the new keyword is used to create an object.

Value type contains data. Reference types contain address referring to a block of memory. Value types are also called direct types because they contain data. Reference types are also called indirect types because they hold the reference to the location where the data is stored.

To understand value type referencing, consider a scenario, where you declare a variable named Num1 as an int and assign the value 50 to it. If you declare another variable Num2 as an int, and assign Num1 to Num2, Num2 will contain the same value as Num1. However, both the variables contain different copies of the value 50. If you modify the value in Num1, the vlaue in Num2 does not change. The following code is an example of value type variables:

int Num1 = 50; //declare and initialize Num1int Num2 = Num1; //Num2 contains the copy of the data in Num1Num1++; //incrementing Num1 will have no effect on the value of Num2

The following figure is a diagrammatic representation of the memory allocated to the value type variable.

Page 66: C#

Note:All value types are created on the stack. Stack memory is organized like a stack of booked piled on a rack.

To understand reference types, consider a class named Car. The object Mercedes of the class Car is initialized with Ford, which is also an object of the same class. In this case both Ford and Mercedes will refer to the same object.

The following code is an example of reference type variables

The following figure is the diagrammatic representation of the memory allocated to the reference type variable.

Memory allocated for value type variable

int Num1;Num1 = 50;int Num2;Num2 = Num1;

50

50

Num1

Num2

using System;namespace Ref_Type{

class Car { public int Model; public void Display_Model() { Console.WriteLine(Model); } } class class1 { static void Main(string[] args) { Car Ford = new Car(); Ford.Model = 10; Car Mercedes = Ford; Mercedes.Display_Model(); Ford.Display_Model(); } }}

Page 67: C#

Note:

All reference types are created on the heap. Heap memory is like books arranged next to each other in rows.

We have discussed int as a value type in the preceding examples, which is a built-in data type. There are more value types like, structures and enumerations, which are user-defined data types. We also discussed class as reference type. There are more examples are reference types like arrays and collections.

Using Structures

A structure is a value type data type. When you want a single variable to hold related data of various data types, you can create a structure. To create a structure you use the struct keyword.

For example, if you want to maintain bill details, such as inv_No, ord_St, custName, product, cost and due_Amt, in a single variable, you can declare a structure. The following code shows the syntax of a structure data type:

struct Bill_Details { public string inv_No; //invoice Number public string ord_Dt; //Order Date public string custName; // Customer Name public string product; //Product Name public double cost; //Cost of the product public double due_Amt; //Total Amount Due }

Like classes, structures contain data members which are defined within the declaration of the structure. However, structures differ from classes and the differences are:

Structures are value types and they get stored in a stack Structures do not support inheritance Structures cannot have default constructor

The following program uses the Bill_Details structure:

Car Ford = new Car();Ford.Model = 10;Car Mercedes;Mercedes = Ford;

***

***

Ford

Mercedes 10

Page 68: C#

using System;namespace Bills{

public struct Bill_Details { public string inv_No; public string ord_Dt; public string custName; public string product; public double cost; public double advance_Amt; public double due_Amt; } class TestStructure { public static void Main(string[] args) { Bill_Details billObj = new Bill_Details(); billObj.inv_No = "A101"; billObj.ord_Dt = "10/10/0"; billObj.custName = "Joe"; billObj.product = "Petrol"; billObj.cost = 100; billObj.advance_Amt = 50; billObj.due_Amt = 50; Console.Clear(); Console.WriteLine("Invoice number is {0}", billObj.inv_No); Console.WriteLine("Order Date is {0}", billObj.ord_Dt); Console.WriteLine("Customer Name is {0}", billObj.custName); Console.WriteLine("Product Name is {0}", billObj.product); Console.WriteLine("Cost is {0}", billObj.cost); Console.WriteLine("Advance Amount is {0}", billObj.advance_Amt); Console.WriteLine("Due Amount is {0}", billObj.due_Amt); } }}

Using Enumerations

Enumerations is a value type data type, which means that enumeration contains its own values and cannot inherit or cannot pass inheritance. Enumerator allows you to assign symbolic names to integral constants. For example, you may want to write a program to represent the weekdays in a program. You could use the integers 0, 1, 2 and 3 to represent Saturday, Sunday, Monday and Tuesday respectively. This representation would work, but it has a problem. It is not convinient. If the integer value 0 is used in code, it would not be obvious that 0 represents Saturday or Sunday. To overcome such a problem, you can use enumeration. To enumerate, you can use the enum keyword.

Declaring an Enumeration

To declare an enumeration type called Days, where the values are restricted to the symbolic names of the weekdays, use the following code:

enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri };

Page 69: C#

The names of days must appear within the braces and must be separated by commas. The enumeration type associates a numeric value with every element. By default, the sequence of values starts from 0 for the first element and goes forward by incrementing 1 each time.

Implementing Enumerations

After declaring the enumeration type, you can use the enumeration type in the same manner as any other data type, as shown in the following code:

using System;namespace EnumDays{

class EnumTest { enum Days { Sat, Sun, Mon, Tue, Wed, Thu, Fri }; static void Main(string[] args) { int First_Day = (int)Days.Sat; int Last_Day = (int)Days.Fri; Console.WriteLine("Sat = {0}", First_Day); Console.WriteLine("Fri = {0}", Last_Day); Console.ReadLine(); } }}

In the preceding code, the enum has been declared as Days. Thi enum has symbolic names, which appear wihtin braces. In the class EnumTest, Main() function displays the values of enum Days. The local variable First_Day and Last_Day holds the value of enum and displays the value Sat and Sun as an output.

Implementing Arrays

An array is a collection of values of the same data type. For example, you can create an array that stores 10 integer type values. The variables in an array are called the array elements. Array elements are accessed using a single name and an index number representing the position of the element within the array. Array is a reference type data type. The following figure shows the array structure in the system’s memory.

Declaring an Array

Array Name IndexIndex

Value 0 Value 6

Page 70: C#

An array needs to be declared before it can be used in a program. You can declare an array by using the following statement:

Datatype[] ArrayName;

The explanation of the elements of the preceding statement is as follows: Datatype: Is used to specify the data type for the elements, which will be stored in the

array. [ ]: Is used to specify the rank of the array. Rank is used to specify the size of the array. Arrayname: Is used to specify the name of the array using which the elements of the

array will be initialized and manipulated.

The following is an example of the array declaration:

int[] Score;

Initializing and Assigning Values to Array

Declaring an array variable does not initialize the array in the memory. When the array variable is initialized, you can assign values to the array elements.

Initializing Array

Array is a reference type, therefore you need to use the new keyword to create an instance of the array. You must have noticed that while declaring the array, the size of the array, the size of the array was not mentioned. The size of the array is specified while it is initialized. The following statement is an example of array initialization:

int[] Score; //Array declarationScore = new int[10]; //Array Instance

The preceding two statements can be combined into a single statement, and written as follows:

int[] Score = new int[10];

In C#, the array subscript always starts with zero. Therefore, the preceding statement creates as array of integers containing 10 elements, from 0 and 9.

Assigning Values to the Array

You can assign values to each element of the array by using the index number, which is also called the array subscript of the element. For example, to assign the value 5 to the first element of the array, you can use the following code:

int[] Score = new int[9];Score[0] = 5;

You can also assign values to the array at the time of declaraiton. However, in case of such explicit initialization, you cannot specify the size of the array, as shown in the following example:

int[] Score = { 5, 10, 15 };

The C# compiler implicitly initializes each array element to a default value depending on the array type. For example, integer array would be initialized by 0 implicitly by the compiler.

Page 71: C#

You can also create and initialize can integer array containing 10 elements, as shown in the following code snippet:

int[] Score = new int[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

In the preceding statement, the only curly braces ( {} ) are used to initialize the array elements.

int[] Source = new int[10] { 0, 1, 2, 3, 4 };int[] Target = Source;

In the preceding statement, if you declare the array, you can omit the size of the array. This is shown in the following statement:

Copying an Array

When an array is initialized, you can access the element values and manipulate them. The following code is an example of array manipulation:

//code to check a palindrome character arrayusing System;namespace MultipleArray{

class Palindrome { static void Main(string[] args) { char[] Str = new char[10]; //Enter the palindrome string Console.WriteLine("Enter the Palindrome String (Max 10 char):"); //Accepting a string and converting into char array Str = Console.ReadLine().ToCharArray(); //Calling the checkPalindrome method Console.WriteLine(checkPalindrome(Str)); Console.ReadLine(); } private static bool checkPalindrome(char[] myString) { int startChar; int lastChar; startChar = 0; //using Length method to calculate the total characters in the array lastChar = myString.Length - 1; //Executing the loop till the last character in the array while (startChar < lastChar) { //checking if the arrays from both the ends are equal if (myString[startChar] == myString[lastChar]) { startChar++; lastChar--; }

Page 72: C#

else { return false; } } return true;

} }}

In the preceding example, a character array is declared and initialized. The value in the array is entered by the user, which is expected to be a palindrome. Length() method is used to calculate the length of the array myString and stored in a variable named lastChar. While storing the length, the value is decreased by 1 because the subscript index number of the array starts with 0. The while loop is used to repeat the statements for comparing the characters in the array. == operator is used to check the equality of characters in the array.

Many other loops are used to manipulating arrays. The foreach loop is however specifically used for manipulating arrays.

Foreach usage

A statement that iterates through an array and executed the same set of instructions on each element is very common. You can use any looping construct to iterate through an array, but the foreach statement interprets the common looping process by removing the need for you to check the array size.

The following is the syntax of the foreach statement:

foreach(type identifier in expression) statement-block

The following code has a set of instructions to declare an array called Numbers, process an array with the foreach statement, and write the values to the console, one line at a time:

using System;namespace ForEach{

class ForEachExample { static void Main(string[] args) { int[] Numbers = {4,3,2,1,0,-1,-2,9,5}; Console.WriteLine("The contents of an array is:"); foreach (int K in Numbers) { Console.Write("{0} \t", K); } Console.ReadLine();

} }}

Page 73: C#

Similar to other data types, you can also pass arrays as parameter to a method.

Param Arrays

While declaring a method if you are not sure about the number of arguments passed as a parameter, you can use the param array.

The following code is an example of using the param array in the methods parameter list:

using System;namespace ParamArrays{

public class ParamExample { public int Adding_ArrayElement(params int[] List) { int Total = 0; foreach (int I in List) { Total += I; } return Total; } } class Tester { static void Main(string[] args) { ParamExample Param_Exam = new ParamExample(); int Total = Param_Exam.Adding_ArrayElement(1,2,3,4,5,6,7); Console.WriteLine("The result is {0}", Total); Console.ReadLine();

} }}

Note:In the parameter list of a method, param array should be the last parameter.

Activity: Matrix Subtraction Using Arraysd.

Problem Statement

David, a student of California University, is currently pursuing B.Sc(IT). He is working on a project named Matrix Subtraction. He needs to perform the following tasks for his project:

Accept data in two arrays Perform the subtraction operation Verify the value of subtraction

Help David to create the C# program using Visual Studio IDE.

Solution

Page 74: C#

To solve the preceding problem, David needs to perform the following tasks:1. Create a Console-based application for Matrix subtraction.2. Build and execute an application

Task 1: Creating a Console-Based Application for Matrix Subtraction

To create a console-based application for Matrix subtraction, David needs to perform the following steps:

1. Select Start All Programs Microsoft Visual Studio 2005 Microsoft Visual Studio 2005. The Start Page – Microsoft Visual Studio window will be displayed

2. Select File New Project. The New Project dialog box will be displayed3. Select the project type as Visual C# from the Project types pane and Console

Application from the Templates pane.4. Type the name of the new project as MatrixSubtractionApp in the Name text box.5. Specify the location where the new project is to be created as c:\chapter5\Activity in the

Location combo box.6. Click the OK button.7. Open the Solution Explorer window and right-click the Program.cs file.8. Select the Rename option and type the new name as MatrixSubtraction.cs

Note:While renaming the Program.cs file, the Microsoft Visual Studio message box “You are renaming a file. Would you also like to perform a rename in this project of all references to the code element ‘Program’?” might appear. Click the Yes button to proceed.

9. Double-click the MatrixSubtraction.cs file in the solution explorer window. The code view of the MatrixSubtraction.cs file is displayed

10. Replace the existing code with the following code:

using System;namespace MatrixSubtractionApp{ class MatrixSubtraction {

public void subtract() { int[] Array1; int[] Array2; int[] Array3;

Array1 = new int[3] { 2, 3, 4 }; Array2 = new int[3] { 1, 2, 3 }; Array3 = new int[3];

Console.WriteLine("The Contents of the Array 1 is:"); for (int i = 0; i < 3; i++) { Console.WriteLine("{0} \t", Array1[i]); } Console.WriteLine("The Contents of the Array 1 is:"); for (int i = 0; i < 3; i++) {

Page 75: C#

Console.WriteLine("{0} \t", Array2[i]); } //Subtraction of Array for (int i = 0; i < 3; i++) { Array3[i] = Array1[i] - Array2[i]; } //Display the Contents of Final Array Console.WriteLine("\n The Result of Array Subtraction is:"); for (int i = 0; i < 3; i++) { Console.WriteLine("{0} \t", Array3[i]); } } static void Main(string[] args) { MatrixSubtraction obj = new MatrixSubtraction(); obj.subtract(); Console.ReadLine(); } }

}

Task 2: Building and Executing an Application

To build and execute the application, David needs to perform the following steps:1. Select Build Build Solution or press F6 to build the solution2. Select Debug Start Debugging or press F5 to execute the application3. Verify the output of the application

Multidimensional Arrays

The rank value of the array is also known as the dimension of the array. The arrays declared and used in the preceding examples are the single dimensional arrays. In single dimensional array, values are stored in a row. You can also declare a multidimensional array, which stores data using a different dimension. The following figure is a graphical representation of a single dimensional array and a multidimensional array.

The following code is an example of a multidimensional array:

int[] Num;int[] Num; int[,] Num;

0 1 2 3 4

0

1

0 1 2 3 4

Single and MultiDimensional Array

Page 76: C#

using System;using System.Collections.Generic;using System.Text;

namespace MultiDimArray{ class MultiArrayExample { static void Main(string[] args) { int sum = 0; int rowSum; int[,] mArray = new int[2, 4] { { 2, 2 }, { 3, 3, 3, 3 } }; for (int row = 0; row < 2 ; row ++) { rowSum = 0; for (int col =0; col <4; col++) { Console.Write("{0} \t)", mArray[row,col]); rowSum = rowSum + mArray[row, col]; } sum = sum + rowSum; Console.Write("= {0}", rowSum); Console.WriteLine(); } Console.WriteLine("The sum of the array is :{0}", rowSum); Console.ReadLine(); } }}

Avani’s Note : Error at the initialization.

The Array Class

The Array class is the base class for all the arrays in C#. The Array class is defined in the System namespace. The Array class provides properties and methods to work with arrays.

Properties

The following table explains some of the most commonly used properties of the Array class

Properties Explanation

Length Returns the total number of items in all the dimensions of an arrayRank Returns the total number of items in all the dimensions of an arrayIsFixedSize Returns a value indicating if an array has a fixed size or notIsReadOnly Returns a value indicating if an array is read-only or not

Commonly Used Array Class Properties

Methods

Page 77: C#

The following table explains some of the most commonly used methods of the Array class.

Properties ExplanationSort Performs sort operation on an array passed to it as a parameterClear Removes all items of an array and sets a range of items in the array to 0GetLength Returns the number of items in an ArrayGetValue Returns the value of the specified item in an ArrayIndexOf Returns the index of the first occurrence of a value in a one-dimensional Array

or in a portion of the ArrayCommonly Used Array class Methods

Using Collections

Arrays are useful, but they have their own limitations. Arrays are used to collect the elements of same data type. The .NET Framework provides several classes that also collect elements in specialized ways. These classes are the Collection classes, and are declared in the System.Collections namespace and sub-namespaces.

The collection classes accept, hold, and return their elements as items. The element type of a collection class is an object. To understand this, contrast an array of int variables (int as a value type) with an array of objects (object is a reference type). int is a valu type, and an array of int variables holds its int values directly, as shown in the following figure

In the preceding figure, consider the effect when the array is an array of objects. You can still add integer values to this array. The int data type which is value type is automatically econverted to reference type. This action is called boxing, as shown in the following figure

Value Stored in an int Array

Array

@ 9 7 3 2

int[] array = { 9,7,3,2};

STACK HEAP

Page 78: C#

The element type of a collection class is an object. This means when you insert a value in to a collection, it is always boxed. When you remove the value from the collection, you must unbox it by using a cast. Unboxing means converting from reference type to value type.

The following are the various classes of the System.Collection namespace.

Class Description Use ExampleArrayList Represents the ordered

collection of an object that can be individually indexed

Is used when you want to access elements by using an index. In almost every situation, an ArrayList is a good alternative to an array

Items can be inserted or removed at any position in a mailbox

Queue Represents a first_in, first_out collection of object

Use queue when you need first_in, first_out access.A queue is often used to hold elements that are discarded immediately thereafter, such as information in a buffer

Waiting in a queue for booking a ticket. You join the end of the queue and leave the beginning of the queue.

Requests coming over a network are queued and then discarded after they are processed

Stack Represents a simple last_in, first_out collection of objects

Use a stack when you need last_in, first_out access. A stack is often used to hold items during calculations

A pile of plates, in a cupboard, where you place the plates on top, and also remove them from the top.

Hash Table

Uses a key to access the elements in the collection

Use a hash table when you must access elements by using an index and you can identify a useful index value

You can access book titles by their ISBN numbers

Various Collection Classes

Boxing

Array

@ @ @ @ @

int[] array = { 9,7,3,2};

7 2

9 7

STACK HEAP

Page 79: C#

The ArrayList Class

When you want to access the elements of an array through its index value location in an array, use an ArrayList. The use of the ArrayList is an alternative to the use of the array, which has limitations.

The limitations are: To resize an array, you have to create a new array, copy the elements into the new array,

and then rearrange the array references. To remove an element from an array, you need to create a copy of the element and then

shift all the remaining elements up. To add an element in between an array, you have to shift an element down by one place

to empty a slot. However, you can lose the last element of the array.

The following table describes the use of various methods of an ArrayList class.

Method UseAdd Adds an object to the end of the ArrayListRemove Removes the element at the first occurance of a specific object from the

ArrayListClear Removes all the elements from the ArrayListInsert Inserts an element into the ArrayList at the specified IndexTrimToSize Sets the capacity to the actual number of elements in the ArrayListSort Sorts the elements in the ArrayListReverse Reverses the element in the ArrayList

Methods Used in the ArrayList Class

NoteYou cannot use the Remove method in a foreach loop that iterates through an ArrayList.

Practice Questions

1. If an array is declared as, int[] arr = new int [5], the total number of elements in the array is _____

a. 5b. 2c. 1d. 0

2. Consider the following codeint Number1 = 0;

int Number2 = 0; int[] Array1 = new int[] { 2,3,4,5,6,7,8,9,10,11}; foreach (int Ctr in Array1) { if (Ctr % 2 == 1) Number1++; else Number2++; Console.WriteLine(Ctr);

}

What is the output of the code:a) 3,5,7,9,11

Page 80: C#

b) 2,4,6,8,10c) Ctrd) 2,3,4,5,6,7,8,9,10,11

3. If an array is declared as string [] arr = new string [5], the base type of the array is ______a. stringb. intc. longd. byte

4. Consider the following codeusing System;class ArrayClass

{ static void Main(string[] args) { string[] String_Array = new string[4]; String_Array[0] = "str1"; String_Array[1] = "str2"; for (int i = 0; i < 2; i++) { Console.WriteLine("arr[{0}] = {1}", i, String_Array[i]); } }

}

View the problem statement and answer the following question. what is the output of the program?

a) str1b) str2c) Error Message is displayedd) arr[0] = str1

arr[1] = str25. The subscript number of an array starts from

a. 0b. -1c. 1d. 2

Summary

In this chapter, you learned that: Memory allocated to variables of two types, value type and reference type Value types are the simplest types in C#. Variables of value types directly contain their

data in the variable Reference type variables contain only a reference to data. The data is stored in a

separate memory area A value type variable in the stack A reference type variable holds a reference to an object in the heap. To hold related data of various data type in single variable, structures are used C# provides the features of enum to create user defined data types with numbers as an

index value to access them An array is a collection of values of the same data type The foreach statement interprets the common loop process and removes the need for

you to check the array size. Param arrays are used in the methods with parameter list when the total number of

parameters is not known

Page 81: C#

The .NET Framework provides several classes that also collect elements together in other specialized ways. These are the collection classes, and they live in the System namespace

ArrayList is useful when you want to manipulate the values in an array easily

Exercises

Exercise 1

David is working on a project where he needs to accept the total number of array elements and values from the user. he also needs to arrange the array elements in ascending order, and display the result

Hint: The array should be an integer array

Exercise 2

David is working on an application where he needs to accept the size of an array and its values. He needs to identify the largest and smallest number in the array and based on that he needs to display the result.

Page 82: C#

Chapter 6

Constructors and Destructors

Constructors and destructors perform special functions as members of classes. Constructors are used to initialize objects. Conversely, you can use destructors to delete an object when it is not required.

This chapter introduces the concept of constructors and destructors. In addition, the chapter explains how to implement constructors and destructors. The chapter also explains how constructors and destructors help in identifying the life cycle of the object.

Objectives

In this chapter, you will learn to: Implement constructors Implement destructors Identify the life cycle of an object

Implementing Constructors

A constructor is a special type of method that is invoked when you create a new instance of a class. A constructor is used to initialize the members of a class. The name of a constructor is the same as the name of the class that contains it.

A constructor is complementary to a destructor. It is good programming practice to use both constructors and destructors.

The Need of Constructors

To initialize member variables, a function can be invoked as soon as the object is created. The following program is an example of writing an initialization function:

using System;namespace Calc{ class Calculator { static int number1, number2, total; public void Initialize() { number1 = 10; number2 = 20; } public void AddNumber() { total = number1 + number2; } public void DisplayNumber() { Console.WriteLine("The Total is : {0}", total); } public static void Main(string[] args) {

Page 83: C#

Calculator c1 = new Calculator(); c1.Initialize(); c1.AddNumber(); c1.DisplayNumber();

} }}

In the preceding example, the c1 object of the Calculator class has to call the Initialize() member function to initialize the data members number1 and number2. however, you need to ensure that the initialization function is invoked.

OOP offers you a solution to overcome the preceding problem related to ensuring for invoking he initialize function. While designing a class, you can include a special member function within the class. This member function is executed whenever an object of the class is created. Such functions are called constructors.

Types of Constructors

There are 2 types of constructors, instance constructors and static constructors.

Instance Constructors

An Instance constructor is called whenever an instance of a class is created. These constructors are used to initialize data members of the class. For automatic initialization the Calculator class can be rewritten by using a constructor. For example, consider the following code:

using System;namespace Calc{ class Calculator { static int number1, number2, total; //Constructors have the same name as the class Calculator() { number1 = 10; number2 = 20; } public void AddNumber() { total = number1 + number2; } public void DisplayNumber() { Console.WriteLine("The Total is : {0}", total); } public static void Main(string[] args) { Calculator c1 = new Calculator(); c1.AddNumber(); c1.DisplayNumber();

} }

Page 84: C#

}

In the preceding code notice that there is no return type specified to the Calculator() constructor. This is because constructors do not return values. The variable number1 is assigned with value 10 and number2 is assigned with value 20 when the constructor is invoked by the Common Language Runtime (CLR).

If there are no constructors defined for a class, the compiler creates a default constructor. In such a case, the instantiation of an object of this class invokes the default constructor.

Static Constructors

Static constructors are used to initialize the static variables of a class. These variables are created using the static keyword and they store values that can be shared by all the instances of a class. These constructors have an implicit private access. The constructors will be invoked only once during the execution of a program.

The following example illustrates the implementation of a static constructor:

public class class1 { static int number1; int number2; static class1() { number1 = 10; //OK. Since number1 is a static variable in class1 number2 = 3; //Error. number2 is a non-static variable in class1 } }

Note: In actual practice, constructors are used to initialize data members and not for any input or output operations.

Note:We can have more than one constructor in a class. Chapter 7 discusses this topic in detail.

Constructors with Parameters

Objects can be initialized using the default constructor with values hard-coded in the program. But there might be a requirement where the variables need to be initialized with user supplied values. To tackle this problem, a constructor can be modified to accept the user supplied values at the runtime..

The following code illustrates the use of parameters in constructors:

using System;namespace Calc{ class Calculator { static int number1, number2, total; //Constructors defined with 2 integer parameters num1 and num2 Calculator(int num1, int num2)

Page 85: C#

{ number1 = num1; number2 = num2; } public void AddNumber() { total = number1 + number2; } public void DisplayNumber() { Console.WriteLine("The Total is : {0}", total); } public static void Main(string[] args) { int var1, var2; Console.WriteLine("Enter Value 1:"); var1 = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Enter Value 2:"); var2 = Convert.ToInt32(Console.ReadLine()); Calculator c1 = new Calculator(var1, var2); c1.AddNumber(); c1.DisplayNumber(); Console.ReadLine();

} } }

In the preceding code, the initialization values are passed to the member variables at the time of creating the object after accepting values from the user. Therefore, the following statement:

Calculator c1 = new Calculator(var1, var2);

invokes the constructor function and passes the initialization values supplied by the user at runtime, to the variables num1 and num2, respectively.

Note:In the preceding example, if you try to execute the statement,Calculator c1 = new Calculator(); it would generate an error “No overload for method Calculator takes ‘0’ arguments”.

Implementing Destructors

A destructor has the same name as its class but is prefixed with a ~, which is the symbol of tilde. Destructors cannot be inherited or overloaded. The following code modifies the declaration of the Calculator class by using a destructor:

using System;namespace Calc{ class Calculator { static int number1, number2, total; Calculator()// Constructor

Page 86: C#

{ number1 = 20; number2 = 30; total = 0; Console.WriteLine("Constructor Invoked"); } ~Calculator() //Destructor { Console.WriteLine("Destructor Invoked"); } public void AddNumber() { total = number1 + number2; } public void DisplayNumber() { Console.WriteLine("The Total is : {0}", total); } public static void Main(string[] args) { Calculator c1 = new Calculator(); c1.AddNumber(); c1.DisplayNumber(); } } }

In the preceding code, the .NET Framework automatically runs the destructor to destroy objects in the memory and displays the message “Destructor Invoked”.

Note:To see the input of the preceding program, press Ctrl+F5.

Even when you do not call the destructor, garbage collector releases the memory.

Garbage Collection

Garbage Collection is a process that automatically frees the memory of objects that are no more in use. The decision to invoke the destructor is made by a special program of C# known as the garbage collector. However, an object loses scope at the end of the Main() method, the destructor is not necessarily invoked. Therefore in C#, you cannot determine when the destructor is called. Garbage collector also identifies the objects that are no more referenced in the program and releases the memory allocated to them.

In C#, you cannot destroy an object explicitly in code. In fact, it has the feature of garbage collection, which destroys the objects for the programmers. The process of garbage collection happens automatically. It ensures that:

Objects get destroyed: It does not specify when the object shall be destroyed Only unused objects are destroyed: An object is never destroyed if it holds the

reference of another object.

C# provides special methods that are used to release the instance of a class from memory, Finalize() and Dispose().

Page 87: C#

The Finalize() destructor is a special method that is called from the class to which it belongs or from the derived classes. The Finalize() destructor is called after the last reference to an object is released from the memory. The .NET Framework automatically runs the Finalize() destructor to destroy objects in the memory. However, it is important to remember that the Finalize() destructor may not execute immediately when an object loses scope. This is because Common Language Runtime (CLR) call the Finalize() destructor using a system called reference-tracing garbage collections. In the reference-tracing garbage collection, the CLR periodically checks for objects that are not used by the application. When such an object is found, the Finalize() destructor is called automatically and garbage collector of the CLR releases the object from the memory.

The Dispose() method is called to release a resource, such as database connection, as soon as the object using such a resource us no longer in use. Unlike the Finalize() destructor, the Dispose() method is not called automatically and you must explicitly call it from a client application when an object is no longer needed. The IDisposable interface contains he Dispose() method. Therefore, to call the Dispose() method, the class must implement the IDisposable interface.

Note:An interface defines properties, methods, and events. Interface will be discussed in detail in chapter 8.

Identifying the Life Cycle of an Object

The following code shows the life cycle of an object of the TestCalculator class:

using System;//life cycle of an objectnamespace Objects{ class TestCalculator { TestCalculator() { Console.WriteLine("Constructor Invoked"); } ~TestCalculator() { Console.WriteLine("Destructor Invoked"); } public static void Main(string[] args) { Console.WriteLine("Main() Begins"); TestCalculator calc1 = new TestCalculator(); { Console.WriteLine("Inner Block Begins"); TestCalculator calc2 = new TestCalculator(); Console.WriteLine("Inner Block Ends"); } Console.WriteLine("Main() Ends"); } } }

The explantion of the output is as follows:

Page 88: C#

The calc1 object has function scope. Therefore, its constructor is executed after the execution of the Main() begins

The calc2 object has block scope. Therefore, its constructor is executed after the execution of the Inner Block begins

The destructor of all objects is invoked when garbage collector is invoked.

Just a Minute

Consider the following code snippet:

class Number { static myNumber; public void NumDisplay() { ... } static void Main(string[] args) { Number n1 = new Number(); n1.NumDisplay(); Console.ReadLine(); } }

The Number class has only one, static member variable called mynumber. Which constructor would you use to initlialize mynumber?

Answer:

Static Constructor

Practice Questions

1. Which of the following statement is true about garbage collection?a. In garbage collection the objects are not destroyedb. In garbage collection the objects are destroyed every time.c. In garbage collection only unreferenced objects are destroyed

2. A destructor has the same name as its class but is prefixed with ______

3. _______ process identifies the unused objects and releases them in C#

4. Consider the following code and identify which line will generate an error on compilationusing System;//life cycle of an object

namespace Objects{ class Draw { public void Shape() { Console.WriteLine("in shape method"); } public Draw() //line 1

Page 89: C#

{ Console.WriteLine("this is a constructor"); } public static void Main(string[] args) { Draw obj = new Draw(); //line 2tt obj.Draw(); //line 3 obj.Shape(); //line 4 } }

}

Consider the preceding and answer the following question. which line in the code will generate an error on compilation

a) Line 1b) Line 2c) Line 3d) Line 4

5. The IDisposable interface contains the ______ method

Summary

In this chapter, you learned that

Constructors are member functions of a class and are invoked when an instance of the class to which they belong is created

A constructor has the same name as its class A destructor is invoked when any instance of a class ceases to exist. A destructor has the same name as its class, but it is prefixed with a ~ (tilde) Constructors are special methods that are used to release the instance of a class from

memory Garbage collection is a process that automatically frees the memory of objects that is no

more in use The Finalize() destructor is called after the last reference to an object is released from the

memory The Dispose() method is called to release a resource, such as a database connection,

when the object using such a resource is no longer in use.

Exercises

Exercise 1

Predict the output of the following program

using System;namespace Square_Number{ class CalculateSquare { int number; public void Square(int number) {

Page 90: C#

Console.WriteLine(number); number *= number; Console.WriteLine(number); } CalculateSquare() { number = 10; Square(numbe r); } public static void Main(string[] args) { CalculateSquare cal = new CalculateSquare(); Console.ReadLine(); } } }

Exercise 2

Predict the output of the following program

using System;namespace CalculateNumber{ class Calculate { static int number1; public void Display(int number) { Console.WriteLine(number); } Calculate() { number1++; Display(number1); } static Calculate() { number1 = 10; number1++; } public static void Main(string[] args) { Calculate cal1 = new Calculate(); Calculate cal2 = new Calculate(); Console.ReadLine(); } } }

Page 91: C#

Chapter 7

Polymorphism

Polymorphism is the ability that helps in executing different operations in response to the same message. In OOP, you can implement polymorphism by creating more than one function within a class that have the same name. the difference in functions lie in the number and the types of parameters passed to each function.

This chapter introduces the concept of polymorphism. It explains how to implement function overloading and operator overloading.

Objectives

In this chapter, you will learn to: Describe polymorphism Implemetn function overloading Implement operator overloading

Introducing Polymorphism

The term polymorphism was derived from the Greek words ‘poly’ and ‘morphos’, which mean ‘many’ and ‘forms’, respectively. In OOP, polymorphism is often expressed by the phrase “one interface, multiple functions”. This expression means that polymorphism allows one interface to be used for multiple functions. You can apply polymorphism for reducing the complexity wihtin the functions of a class of your program.

Polymorphism can either be static or dynamic. In static polymorphism the response to a function is decided at compile time. In dynamic polymorphism the response to the function is decided at run time.

Static polymorphism

Static polymorphism refers to an entity, which exists in various forms simultaneaously. The concept of static polymorphism is analogous to the role of a woman who can be a wife, a mother, a daughter, a sister, and an executive at the same time.

The mechanism of linking a function with an object during compile time is called early binding. It is also known as static binding.

C# uses 2 approaches to implement static polymorphism. These are: Function Overloading Operator Overloading

Function Overloading

This approach allows using the same name for 2 or more functions. Each redefinition of a function must use different types of parameters, sequence of parameters, or a number of parameters. The type, sequence, or a number of parameters for a function is called the funciotn signature. When you have multiple functions with the same name, the compiler identifies the function based on the parameters to the function.

Consider an example, to understand the benefit of function overloading where you need a function that convers distance in kilometers to miles, and kilometers can either be an integer or a

Page 92: C#

float. One approach can be to have 2 functions of different names, as shown in the following code:

int ConvertInteger(int km);int ConvertFloat(int km);

Another approach can be using function overloading. You can have 2 functions with the same name but with different parameters, as shown in the following code:

int Convert(int km);float Convert(float km);

Operator Overloading This approach allows user-defined types such as structures and classes, to use overloaded operators for easy manipulation for their objects. Operator overloading can be achieved by defining the static member functions using the operator keyword. For example, you can redefine the + operator or a user-defined class Hour to add the hour value of two class objects. You can then add 2 Hour objects by using the + operator.

The following code is an example showing the usage of operator (+):

Hour h1;Hour h2;

Hour h3; h3 = h1 + h2;

Dynamic Polymorphism

In dynamic polymorphism the decision about function execution is made at run time. Dynamic polymorphism is more useful as compared to static polymorphism because dynamic polymorphism gives much more flexibility for manipulating objects.

The mechanism of linking a function with an object at run time is called dynamic or late binding. Dynamic binding supports virtual functions.

C# uses 2 approaches to implement dynamic polymorphism. These are: Abstract classes: Are the special type of base classes that consist of abstract class

members. All the class members that are derived directly from abstract classes must implement all the abstract functions and properties.

Virtual Functions: Are the functions that do not really exists, however, appear to be present in some parts of the program.

Note:Abstract classes and virtual functions will be taught in detail in chapter 8.

Implementing Function Overloading

Function overloading is the most common way of implementing polymorphism. You can implement function overloading by defining 2 or more functions in a class sharing the same name. However, each definition of a function must differ in its function signature:

The following code is an example of function overloading:

using System;

Page 93: C#

namespace CalculateMax{ class CalculateMax { public int Max(int number1, int number2) { if (number1 > number2) { return number1; } else { return number2; } } public float Max(float number1, float number2) { if (number1 > number2) { return number1; } else { return number2; } } } class MaxCalc { static void Main(string[] args) { CalculateMax calc = new CalculateMax(); Console.WriteLine("{0}", calc.Max(5.4F,8.6F)); //Both function calls differ Console.WriteLine("{0}", calc.Max(19,12)); //only in their parameters Console.ReadLine(); return 0; } } }

In the preceding example, the function Max() displays the maximum of 2 numbers, number1 and number2. the function Max() is overloaded by passing the integer and float values into it.

Funtion Signature

During a funciton call, a C# compiler needs to resolve the name of the function. The signature of a function is defined by:

The number of parameters. Consider the following example:

void AddNumber(int); void AddNumber(int, float);

Page 94: C#

In the preceding code, there are two functions because the number of parameters is different.

The data types of parameters. Consider the following example:

void Display(int); void Display(char);In the preceding code, the two functions are difference because the data types of their parameters are different.

The sequence of parameters. Consider the following example:

void Display(int, char); void Display(char, int);In the preceding code, the two functions are difference because their parameters are specified in different order.

Note:The return type is NOT a part of a function’s signature. Therefore, the following two declarations cannot occur in the same class:

void display();char display();

In addition to function overloading, you can also overload constructor.

Constructor Overloading

Constructors can also be parameterized, and therefore, they can be overloaded. Overloaded constructors are commonly used in C# to provide flexibility while creating an object.

The following is an example of overloading constructors:

using System;namespace Calculate{ class CalculateNumber { private int number1, number2, total; //default constructor public CalculateNumber() { number1 = number2 = total = 0; } public CalculateNumber(int num1, int num2)//Two argument constructor { number1 = num1; number2 = num2; total = 0; } public void AddNumber() { total = number1 + number2; }

Page 95: C#

public void DisplayNumber() { Console.WriteLine("The sum of two numbers is {0}", total); } } class CalNum { static void Main(string[] args) { //Default constructor invoked CalculateNumber cal1 = new CalculateNumber(); //parametric constructor CalculateNumber cal2 = new CalculateNumber(4, 3); cal1.AddNumber(); //add() invoked to calculate the sum of members cal1.DisplayNumber(); cal2.AddNumber();//add() invoked to calculate the sum of members cal2.DisplayNumber(); return 0; } }

}

Activity : Displaying Days using Function Overloading

Problem Statement

Time has to develop an application for primary school. The application should accept the month entered by the student and display the total number of days of that month.

Solution

To develop the required application, Time needs to perform the following tasks:1. Create a console based application2. Build and execution an application.

Task 1: Creating a Console-Based Application

1. Select Start All Programs Microsoft Visual Studio 2005 Microsoft Visual Studio 2005. The Start Page – Microsoft Visual Studio window will be displayed

2. Select File New Project. The New Project dialog box will be displayed3. Select the project type as Visual C# from the Project types pane and Console

Application from the Templates pane.4. Type the name of the new project as PrimarySchool in the Name text box.5. Specify the location where the new project is to be created as c:\chapter7\Activity1 in

the Location combo box.6. Click the OK button.7. Open the Solution Explorer window and right-click the Program.cs file.8. Select the Rename option and type the new name as DayCount.cs9. Double-click the DayCount.cs file in the solution explorer window. The code view of

the DayCount.cs file is displayed10. Replace the existing code with the following code:

Page 96: C#

using System;namespace PrimarySchool{ class DayCount { int Month; int Year; int Days; public DayCount() //constructor to initialize month and year to 0 { Month = 0; Year = 0; } // Returns 1 if year is a leap year, else returns 0 public Boolean LeapYear() { if (Year % 4 == 0) return true; else return false; } //Sets the month and year public void setDate(int month1, int year1) { Year = year1; Month = month1; } //Sets the month, overloaded function public void setDate(int month1) { Month = month1; Year = 2006; } //Returns the name of the month public string monthName() { switch (Month) { case 1: return "January"; case 2: return "February"; case 3: return "March"; case 4: return "April"; case 5: return "May"; case 6: return "June"; case 7: return "July"; case 8: return "August"; case 9: return "September"; case 10: return "October"; case 11: return "November"; case 12: return "December";

default: return "Invalid Month Specified!"; } } //Sets the number of days in a month public void setDays()

Page 97: C#

{ switch(Month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: { Days = 31; break; } case 2: { Days =28; if (LeapYear()) { Days = 29 //Assign 29 days if leap year break; } } case 4: case 6: case 9: case 11: { Days = 30; break; } }

} public void display() { string[] name = new string[25]; setDays(); Console.Write("The number of days in the month of" + monthName()); Console.Write("is" + Days); } static void Main(string[] args) { DayCount dayCount = new DayCount(); int month, year; Console.WriteLine("Enter the month in number:"); month = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Enter the year:"); year = Convert.ToInt32(Console.ReadLine()); dayCount.setDate(month,year); dayCount.display(); Console.ReadLine(); } }

}

Page 98: C#

Task 2: Building and Executing an Application

To build and execute the application perform the following steps:1. Select Build Build Solution or press F6 to build the solution2. Select Debug Start Debugging or press F5 to execute the application3. Verify the output of the application

Implementing Operator Overloading

The concept of overloading a function can also be applied to operators. Operator overloading provides additional capabilities to C# operators when they are applied to user-defined data types. Only the predefined set of C# operators can be overloaded.

Need for Operator Overloading

Most built-in data types have predefined operators associated with them. For example, the C# data types int with the operators +,-,*, and / provides support for mathematical operations. A class is an example of a user-defined data types. To make operations on a user-defined data type is not as simple as the operation on a built-in data type. To use operators with use-defined data types, they need to be overloaded according to a programmer’s requirement.

The following is an example of the Length class that implements the British standard of measuring distance:

class Length { int iFeet; float fInch; public Length(int iFt, float fIn) { iFeet = iFt; fInch = fIn; } void Disp_Len(void) { Console.WriteLine("Length = {0}, {1}", iFeet, f); } }

To add 2 distances stored in 2 objects of the Length class in the preceding example, you need to invoke a function. Consider, you have defined a function named Add_Dist. The following is the code to invoke the function:

object3.Add_Dist(object1, object2);

In this case, object1 is added to object2 and the result is stored in object3.

You might also want to compare two distances. The following code compares two objects of the Length class, using the CompareDistance():

object1.CompareDistance(Object2);

In the preceding code, the member function CompareDistance() of object1 is invoked with object2 as a parameter. This function compares the data members of object1 with those of object2 and returns the difference between them.

Page 99: C#

Instead of using the Add_Dist() to add two distances, it is easier to use the following statement:

object3 = object1 + object2;

In the preceding code, object1, object2 and object3 are all objects of the Length class. This code is an easier way of expressing your intent as opposed to a lengthy function call.

The objects of the Length class can be compared as shown in the following code:

object1 > object2;

or

object1 < object2;

or object1 == object2;

Users can understand the operator notation more easily than a function call because it is closer to real life implementation. Therefore, by associating a set of meaningful operators a user-defined data type can be manipulated in a conventional and simple form. Associating operators with user-defined data types involves overloading them.

The following table describes the overload ability to the operators in C#.

Operators Descriptions+, -, !, ~, ++, -- These unary operators take one operand and can be

overloaded+, -, *, /, % These binary operators take two operands and can be

overloaded==, !=, <, >, <=, >= The comparison operators can be overloaded&&, || The conditional logical operators cannot be overloaded directly,

but they are evaluated using & and \ which can be overloaded+=, -=, *=, /=, %= The assignment operators cannot be overlooked=, ., ?:, new , is, sizeof, typeof These operators cannot be overlookedOverload Ability of Operators

Note:The comparison operators, if overloaded, must be overloaded in pairs: that is, if == is overloaded, ! must also be overloaded. The reverse is also true. Similarly, it is true for < and >, and for <= and >=.

An operator can be overloaded by defining a function to it. The function for the operator is declared by using the operator keyword.

Operators may be considered as functions internal to the compiler. For example, the expression a+b may be taken as +(a,b). A programmer may also overload these functions by writing the appropriate functions with similar signatures. Functions that specify the additional task for the operators are called operator functions. The keyword operator along with the operator to be overloaded is used as the function name.

For example, to overload the + operator, the following syntax is used to define the operator function:

Page 100: C#

Such a definition makes use of operators, realistic and easy to understand. For example, if the ‘+’ operator is overloaded for the class Length, then the process of adding two distance objects will be simple statement, which is object1+ object2 for the user. The compiler interprets the preceding statement as operator + (object1, object2), where the operator function of the first operand of the operator.

Both unary and binary operators can be overloaded

Overloading Unary Operators

Unary operators act on a single operand. Some examples of unary operators are the increment (++) and decrement (--) operators.

Unary operators can be classified as: Simple prefix unary operators, for example the – (minus) operator Pre and post increment and decrement operators, for example the ++() prefix increment

operator

Simple Prefix Unary Operators

A simple prefix operator may be defined by function that takes one parameter. For example, in the following code the compiler resolves ‘object1’ as:

operator - (object1)

The operator - () function can be associated with the class by making it a member function. The operator - () function can be provided an object of the class as its parameter. This effectively associates the class with the function.

The following code is an example of the overlaoding – operator:

using System;namespace Calculator{ class Calculator { public int number1, number2; public Calculator(int num1, int num2) { number1 = num1; number2 = num2; } public static Calculator operator -(Calculator c1) { c1.number1 = -c1.number1; c1.number2 = -c1.number2; return c1; } public void Print() { Console.WriteLine("number1 = " + number1); Console.WriteLine("number2 = " + number2); Console.ReadLine(); } }

Page 101: C#

class EntryPoint { static void Main(string[] args) { Calculator calc = new Calculator(15, -25); //Using the overloaded - operator with the class object calc = -calc; calc.Print(); } }}

In the preceding code, - operator is overloaded to make the variables of class Calculator negative. In the statement calc = -calc, the operator is used with the object of the class Calculator, which calls the operator overload and makes the variables negative.

Pre and Post Increment and Decrement Operators

The increment operator increments the current value of an operand by 1 and returns the result. The decrement operator decrements the current value of an operand by 1 ad returns the result.

When the increment and decrement operators are used, the value of the variable is the same after the operation is completed. The difference in the value of the variable between the prefix and postfix notation is the order in which they are applied.

There are certain rules, which are applied when declaring the prefix and postfix notations; the notations must be public, static and unary. The following is an example of the increment operator for the Watch struct:

struct Watch { private int val; ...... public static Watch operator++ (Watch parameter)) { parameter.val++; return parameter; } ..... }

In C#, the single operator is used for both the prefix and postfix operators. The result of a postfix notation is the value of the operand before it takes place. The following example statements give the usage of postfix notation:

Watch w = new Watch(6);Watch postFix = w++;

The preceding statements will result in assigning the value of variable w to variable postFix and then incrementing the value of variable w.

The result of a prefix expression is the return value of the operator. The following example statements give the usage of prefix notation:

Watch w = new Watch(6); Watch preFix = ++w;

Page 102: C#

The preceding statements will result in incrementing the value of variable w and then assigning the value of variable w to object preFix.

The following is an example of overloading the pre increment and post increment operator, using structures:

using System;using System.Collections.Generic;using System.Text;

namespace OperatorOverload{ struct NumberCount { public int i; public NumberCount(int initval) { this.i = initval; } public static NumberCount operator ++(NumberCount arg) { arg.i++; return arg; } } class TestClass { static void Main(string[] args) { NumberCount count1 = new NumberCount(1); NumberCount count2 = count1++; Console.WriteLine(count1.i); Console.WriteLine(count2.i); count2 = ++count1; Console.WriteLine(count1.i); Console.WriteLine(count2.i); Console.ReadLine(); } }}

You can also overload the prefix and postfix notations in classes.

Note:The implementation of increment and decrement operator overlaoding is different in classes as compared to structs.

Operators in Classes

The implementation of the increment operator used with structs cannot be implemented with classes. If Watch is a class, assigning of variable w to postFix makes the varaible postFix refer to the same object as w. updating w will automatically update postFix.

For example:

Operator + (a,b);

Page 103: C#

The following code is an example of using simple binary operators:

using System;using System.Collections.Generic;using System.Text;

namespace BinaryOverload{ class Calculator { public int number; public Calculator() { number = 0; } public Calculator(int n) { number = n; } public static Calculator operator +(Calculator calc1, Calculator calc2) { Calculator calc3 = new Calculator(); calc3.number = calc2.number + calc1.number; return calc3; } public void display() { Console.WriteLine("{0}", number); } } class CalNum { static void Main(string[] args) { Calculator num1 = new Calculator(100); Calculator num2 = new Calculator(50); Calculator num3 = new Calculator(); num3 = num1 + num2; num1.display(); //displays 100 num2.display(); //displays 50 num3.display(); //displays 150 Console.ReadLine(); } }}

In the preceding code, the + operator is overloaded to add two objects of the Calculator class. The operator function recieves one object as a parameter. In the preceding code, num1 is an object of a class, of which the operator is a member function. Object num2 is passed as a parameter to the operator. When an overloaded operator is invoked, the object on the left of the parameter is a member and the object on the right of the operator is the parameter.

Page 104: C#

Activity: Overloading an Operator

Problem Statement

Funcity Land is a newly established amusement park located in West Virginia. Brad is a chief technical officer of Funcity Ladnd. He is currently working on a project related with calculating distances. This project will calculate the distance to reach Funcity Land from various locations because many visitors do not know the exact location of the park.

Brad needs to develop a program, which would enter a visitor’s location and the distance traveled by the visitor. After analyzing the location and the distance travelled by the visitor, the program should display the remaining distance and the total distance traveled

Help Brad to develop an application by overloading by binary operator(+).

Solution

To develop the required application, Time needs to perform the following tasks:3. Create a console based application4. Build and execution an application.

Task 1: Creating a Console-Based Application

11. Select Start All Programs Microsoft Visual Studio 2005 Microsoft Visual Studio 2005. The Start Page – Microsoft Visual Studio window will be displayed

12. Select File New Project. The New Project dialog box will be displayed13. Select the project type as Visual C# from the Project types pane and Console

Application from the Templates pane.14. Type the name of the new project as FunCityLand in the Name text box.15. Specify the location where the new project is to be created as c:\chapter7\Activity2 in

the Location combo box.16. Click the OK button.17. Open the Solution Explorer window and right-click the Program.cs file.18. Select the Rename option and type the new name as Distance.cs19. Double-click the Distance.cs file in the solution explorer window. The code view of the

Distance.cs file is displayed20. Replace the existing code with the following code:

using System;using System.Collections.Generic;using System.Text;

namespace FunCityLand{ class Distance { int Length; public Distance() { Length =0; } public static Distance operator +(Distance Distance1, int Value) { Distance1.Length += Value; return Distance1;

Page 105: C#

} public void DisplayDistance(int Length, int Distance2) { int Result; Console.WriteLine("The distance travelled is {0}", Length); Console.WriteLine("The remaining distance to reach the destination is {0}", Distance2); Result = Distance2 + Length; Console.WriteLine("The total distance you have to travel is {0}", Result); } } class EntryPoint { public static void Main(string[] args) { Distance Distance1 = new Distance(); string Location; int TravelledDistance; Console.WriteLine("Enter the location you have reached: A, B, C"); Location = Console.ReadLine().ToUpper(); if (Location == "A" || Location == "B" || Location == "C") { Console.WriteLine("Enter the distance you have covered:"); TravelledDistance = Convert.ToInt32(Console.ReadLine()); switch(Location) { case "A": Distance1.DisplayDistance(TravelledDistance, 15); break; case "B": Distance1.DisplayDistance(TravelledDistance, 20); break; case "C": Distance1.DisplayDistance(TravelledDistance,25); break; } } else Console.WriteLine("Incorrect Value"); Console.ReadLine(); } }

Task 2: Building and Executing an Application

To build and execute the application perform the following steps:1. Select Build Build Solution or press F6 to build the solution2. Select Debug Start Debugging or press F5 to execute the application3. Verify the output of the application

Page 106: C#

Practice Questions

1. Which of the following options about implementing polymorphism is not true?a. You can implement polymorphism by implementing an interfaceb. You can also achieve polymorphism by inheritancec. You can implement polymorphism by encapsulationd. You can implement polymorphism by using abstract classes

2. Consider the following statements:

Statement A: In dynamic polymorphism, appropriate methods of a program can be invoked, depending in the context.

Statement B: In early binding, function calls are bound at run time.Which of the following options is true about these statements

a. Statement A is true and Statement B is false.b. Statement A is false and Statement B is truec. Both statements are trued. Both statements are false

3. Which of the following is an example of function overloading?a. Void example(); char exmaple();b. void exmaple1();void exmaple2();c. void exmaple1(int, int);void exmaple2(float, float);d. void exmaple1(int, int);void exmaple1(float, float);e.

4. Consider the following statements

Statement A: Overloading a binary operator is similar to overloading a unary operator except that a binary operator requires an additional parameter

Statement B: Binary operators include arithmetic assignment operators..Which of the following option is true about these statements?

a. Statement A is true and Statement B is false.b. Statement A is false and Statement B is truec. Both statements are trued. Both statements are false

5. Which of the following statements is true about operator overloadinga. The + operator cannot be overloadedb. Binary operators are operators that work with two operands.

Summary

In this chapter, you learned that: The term polymorphism has been derived from Greek words ‘poly’ and ‘morphos’, which

means ‘many’ and ‘forms’, respectively. Polymorphism allows one interface to be used for multiple functions. Static polymorphism refers to an entity, which exists in different forms simultaneously In dynamic polymorphism the decision about function execution is made when code is

executed

Page 107: C#

Function overloading is the process of using the same name for two or more functions in a class.

The number, type, or sequence of parameters of a function is called its function signature Overloaded constructors are commonly used in C# to provide flexibility while creating an

object Operator overloading provides additional capabilities to C# operators when they are

applied to user-defined data types. The predefined C# operators can be overloaded by using the operator keyword. Operators may be considered as functions internal to the compiler. Operators may be classified as unary and binary operators. Unary operators work with one operand and are classified as: A prefix unary operator may be defined by a member function that takes no parameters

or by a nonmember function that takes one parameter Binary operators work with two operands Overloading a binary operator is similar to overloading a unary operator, except that a

binary operator requires an additional parameter.

Exercises

Exercise 1

Write a program, which increments the number of pages of a book by the number of pages entered by the user.

Page 108: C#

Chapter 8

Inheritance

Entities do not exist in isolation. They have some type of relationship with each other. Similarly, in C#, the classes in a program can be related to each other. Identifying and establishing relationships between classes is a critical aspect of OOP.

This chapter identifies the relationship between classes. It discusses the use of classes and inheritance. In addition, this chapter discusses the use of abstract classes, sealed classes and interfaces.

Objectives

In this chapter, you will learn to: Identify relationships between classes Use classes and inheritance Use abstract classes Use sealed classes Use interfaces

Identifying Relationships between Classes

In software application classes and objects are related to each other. They act and react with other classes and objects. Depicting their dynamism in an application makes the application as close as possible to the real world.

In the object oriented approach, objects perform actions in response to messages from other objects defining the receiving object’s behavior. This approach specifies the relationships among classes based on the behavior of individual class.

Consider the similarities and differences among the objects or classes, including an automobile, a car, a driver, and an engine. You can make the following observations:

A truck is a kind of an automobile A car is another kind of an automobile. An engine is part of an automobile A driver drives a car

Based on the preceding observations, you can identify the relationships among the objects and classes.

Kinds of Relationships

There are various relationships between objects of different classes in an object-oriented environment:

Inheritance relationship Composition relationship Utilization relationship Instantiation relationship

Inheritance Relationship

OOP enables classes to inherit commonly used state and behavior from other classes. Consider the following example:

Page 109: C#

Automobile is the superclass of a car and a bus. Car and bus inherits attributes and behavior from the automobile. The car, bus, and automobile have a relationship where one object is a type of another object. This means that every car is an automobile, but every automobile is not a car. This type of relationship is known as inheritance. In C# programming, each class is allowed to inherit from one class and each class can be inherited by unlimited number of classes.

In terms of classes, inheritance means that a class may inherit a set of attributes from another class. The following figure is an example of the hierarchy establishing the inheritance relationship of the Mammals class.

In the preceding figure, notice there is a set of classes: mammals, dogs, cats, humans, lions, tigers and leopards. Mammals have the following set of characteristics:

Are warm blooded Are vertebrates Have external ears Have hair on their body

The dog, cat and human classes also have similar characteristics and they have inherited these attributes from the Mammals class.

Similarly, you can establish the relationship between a superclass and its subclasses.

The simple hierarchy of Mammals

Mammals

Dogs HumansCats

LeopardsTigersLions

Page 110: C#

Superclass and Subclass

The following figure shows the hierarchy of the subclass of the superclass.

In the preceding figure, notice both the Car and Bus classes inhertit the characteristics of an Automobile. The Automobile class is a superclass while Bus and Car classes are its subclasses.

Let us continue considering the Automobile class example. An automobile is a vehicle that has an engine. The Automobile class inherits its characteristics from the vehicles class. Some of the attributes of the Automobile class are:

Has wheels Has an engine Has a color

Sometime, you may not want to create an object of the Automobile class in your program. Instead, you may want to use it only because you want it to act as a superclass for the Car and Bus classes. In this case, Automobile is called the abstract superclass because there exists no such entity as an automobile. It is simply used as a superclass from which other classes inherit attributes. The superclass is generalized. Generalization means that multiple classes inherit from the same superclass.

Generalization is needed to create programs that can be customized in accordance with new requirements. Recall the resilience to change is one of the features if OOP. Consider a scenario where you need to write a program that displays a string as an output. The simplest solution to this problem will be to accept a string from a user and display it. However, there is a change in your requirement and you want the output to be an integer. What will you do in such a case?

You have a superclass data, which has a show method to display its value. You also have character and float as the subclasses of data. To display an integer, you need to create a class called integer, which is a subclass of data. Adding a new subclass will not affect the existing classes. Therefore, you do not need to add a method show to each subclass because the superclass has this method, and the subclasses will inherit the method.

Reusability is another important reason for a programmer to generalize. Generalization is implemented by using an abstract superclass, which is a conceptual class. An abstract class

Automobile

Car Bus

Ford BMW Toyota Mitsubishi

Page 111: C#

does not exist in the real world but acts as a base from which other classes inherit properties. Generalization ensures that all subclasses have a consistent interface.

For example, consider the GeometricalFigures class that has several subclasses, such as Square, Triangle and Polygon. The GeometricalFigures class has attributes called numberOfCoordinates and valueOfCoordinates. It also contains the getCoordinates and draw functions. The getCoordinates function prompts the user to type the values of coordinates.

In case of a square, the value of numberOfCoordinates is four. A user will be prompted to enter four coordinates. In case of a polygon, the user can enter five or more coordinates. To draw a triangle, you will prompt the user to input three coordinates. Using these coordinates, the user can call the draw function to create a triangle.

Another way to draw geometrical figures is to allow each subclass to have its own method getCoordinates, and then draw them by using those coordinates as parameters. These methods would have to be repeated in all the subclasses. The triangle class, for instance, might ask for the Y coordinate and then for the X coordinate. The square class might do exactly the opposite.

Repeating methods can lead to confusion caused with the inconsistency in the interface. It would be simpler to have the getCoordinates and draw methods in the superclass. These methods will be inherited by subclasses ensuring uniformity across all GeometricalFigures.

While generalizing, the structure and behavior that is common to different classes are combined to form a common superclass. The superclass represents generalization and the subclass represents specialization, where attributes and methods from the superclass are added, modified, or hidden.

In the object-oriented approach, the emphasis is on designing classes so that they share data and methods. At the same time, security has to be maintained. Unauthorized classes should not be allowed to tamper with members of other classes. Encapsulation provides security to the data as well as methods of a class.

There are no set rules to guide when you should generalize and when you should not generalize. However, you should keep some rules in mind while generalizing. The existence of common properties is one such rule. There are no set of rules defined to stop generalizing classes.

For example, consider you are developing a payroll system, where you have the manager, accountant and clerk classes. These are the subclasses of a superclass, employee. Assemble the common properties of these subclasses and put all these in the employee superclass. You do not need to generalize further to include a class called person because the payroll system does not require this kind of generalization.

Just a Minute

Build the hierarchy of the mixer, VCR, color television, washing machine, stereo class objects, and generalize wherever possible.

Answer

The figure shows the hierarchy of the class objects.

Page 112: C#

There can be need to redefine the function of the superclass. This process where the subclasses redefine the function of the superclass is called overriding.

For example, consider the Car and Bus subclasses of he Automobile superclass. The Automobile class has a close_window function. The implementation of this function will be different in Car and Bus. To shut the window, you will roll it up in the case of a car, while you will slide to the windowpane in case of a bus. In this case, the subclasses need to redefine the function.

Composition Relationship

OOP allows you to form an object, which includes another object as its part. This mechanism of forming an object is called composition.

For example, a class named Car consists of an engine. Therefore, a car is composed of an engine. This type of relationship between the car and the engine is known as the composition relationship.

Take another example, consider the passenger class. Each passenger of a train has a ticket. The attributes of a passenger are name, age, gender, meal_preference, and ticket. The ticket class has attributes such as trained, coachNumber, seatNumber, portNumber and fare. Therefore, the passenger class consists of the Ticket class.

Many objects in the real world have this type of relationship. The composition relationship exists when one class is made up of another class.

Just a Minute

Identify the relationship between the following class pairs:

1. Television - Speaker2. Mammal – Tiger3. Garment – Shirt4. Cup – Tea5. Computer – Microprocessor

Answer

The relationships are as follows:

Electronic Items

Entertainment Items Utility Items

Color Television

VCR Stereo Mixer Washing Machine

Page 113: C#

5 and 1 are examples of composition relationships3 and 2 are examples of inheritance relationships4 does not exhibit any relationship. Tea is not an attribute of cup.

Utilization Relationship

OOP allows a class to make use of another class. This kind of relationship is called utilization. For example, BMW is an object of the car class, and Patrick is an instance of a driver. Patrick drives a BMW. Another driver, James, drives a bus. Therefore, both the car and bus classes use the driver class. This type of relationship between a driver and a bus or a driver and a car is known as the utilization relationship.

Take another example: a student writes with a pencil while a painter draws with a pencil. Both the student and painter use the pencil class. The relationship between the student and the pencil, or the painter and the pencil is the utilization relationship

Just a Minute

Identify the classes and their utilization relationship in the following scenario of a departmental store.

There are several counters and each counter in the store is manned by a single salesperson who sells a specific product. A customer approaches a counter. Depending on the customer’s desire to purchase a product, the salesperson sells the product to the customer and accepts payment.

Answer

The utilization relationships of the preceding scenario are:1. Salespersons man counters2. Each counter deals in a specific product3. The customer buys a product4. The customer pays the salesperson.

Instantiation Relationship

An instantiation relationship, as the name suggests, is a relationship between a class and an instance of that class. Some examples of instantiation relationships are:

A BMW is a car A chest of drawers is a piece of furniture ‘Gone with the Wind’ is the title of a book. You are a student.

Using Classes and Inheritance

In C#, inheritance is the property by which the objects of a derived class possess copies of the data members and the member functions of the base class. A class that inherits or derives attributes from another class is called the derived class. The class from which attributes are derived is called the base class. In OOP, the base class is actually a superclass and the derived class is a subclass.

Implementing Inheritance

Page 114: C#

Each instance of the derived class includes the attributes of the base class. Therefore, the derived class has a larger set of attributes than its base class. The derived class can, however, modify some or all the attributes. Inheritance enables the easy maintenance of code. Any change made to the base class automatically changes the behavior of its subclasses. In this class, the subclasses automatically inherit the new behavior.

The syntax used in C# for creating derived classes is as follows:

<access specifier> class <base class>{

. . . }

class <derived_class> : <base_class>{

. . . }

Determining Inheritance Hierarchies

You can use a thumb rule to establish whether inheritance is required while you are designing a program. Always check the kind of relationship between the derived classes and the base class. Ensure the derived class is a kind of the base class. Consider a scenario. You have an Employee class and a Trainee class. You require the properties of the Employee class to exist in the Trainee class. You can ensure the Trainee class has the properties of the Employee class by writing code in the two ways. The following are examples of code:

class Employee { Trainee tn; public void leave() { tn.Calc_Leave(); //call a function of the employee class } : : }Orclass Trainee : Employee { public void leave() { Calc_Leave(); // Function of the base class is available } : : }

Syntactically, there is nothing wrong with the preceding examples. However, one of these examples is a badly designed class. Let us use the rule of thumb. Is a trainee a kind of an employee? The answer is no. Are any trainees employed? The answer is yes. Therefore, in the preceding scenario, it makes more sense to use containment instead of inheritance. The inherited classes can contain constructors and destructors. The invocation of the constructors and destructors also follow the inheritance hierarchy.

Page 115: C#

Invoking constructors

Constructors are called in the order of base-to-derived. However, the execution of destructors cannot be controlled by the programmer.

The following code shows the use of constructors with inherited classes:

using System;class Base { public Base() { Console.WriteLine("Constructor of Base"); } ~Base() { Console.WriteLine("Destructor of Base"); } } class Derived : Base { public Derived() { Console.WriteLine("Constructor of Derived"); } ~Derived() { Console.WriteLine("Destructor of Derived"); } } class BaseDerived { static void Main(string[] args) { Derived obj = new Derived(); } }

Base Class Initialization

In inheritance, the derived class receives the base class member variables and methods. This means that an order of inheritance must be followed during the construction of an object.

The superclass part of the object should be created before you create the subclass part, inclusive of the member objects defined in the derived part. The instructions for superclass initialization are given in the member initialization list, as shown in the following code:

class Point { private int x, y; public Point(int a, int b) { x = a; y = b; }

Page 116: C#

void setX(int a) { x = a; } void setY(int b) { y = b; } int getX() { return x; } int getY() { return y; } ~Point() { x = y = 0; } } class Line : Point { //Member Initialization public Line(int x1, int y1, int x2, int y2) : base(10, 20) { } }

Using Abstract Classes

C# enables you to create abstract classes that are used to provide partial class implementation of an interface. You can complete implementation by using the derived classes. Abstract classes contain abstract methods, which can be implemented by the derived class. Polymorphism can be implemented by using abstract classes and virtual functions. When you create derived classes, you provide more specialized functionality; polymorphism enables you to treat the new objects as general objects:

The following code is an example of the declaration of an abstract class:

abstract class ExampleAbsract //this is an abstract class { ..... } class TestAbstract { static void Main(string[] args) { ExampleAbsract obj = new ExampleAbsract(); //abstract class cannot be instantiated

} }In the preceding code the abstract class is created by using the abstract keyword. There are certain rules governing the use of an abstract class. The rules are:

Cannot create an instance of an abstract class Cannot create an abstract method outside an abstract class Cannot be declared sealed

Page 117: C#

Note:

Sealed classes can never be inherited.

Using Abstract Methods

When using inheritance relationship, you can have a situation where you want to method in a class to be implemented differently in the derived classes but not by the base class itself. Abstract methods are the methods without any body. The implementation of an abstract method is done by the derived class. When a derived class inherits the abstract method from the abstract class, it must override the abstract methods. This requirement is enforced at compile time, and is also called dynamic polymorphism.

The syntax for using the abstract method is

[access-modifiers] abstract return-type method-name ([parameters])

The following code is an example of using abstract classes with abstract methods:

using System;abstract class Animal { public abstract void FoodHabits(); } class Carnivorous : Animal { public override void FoodHabits() { Console.WriteLine("The Carnivorous animals eat only meat"); } } class Herbivorous : Animal { public override void FoodHabits() { Console.WriteLine("The Herbivorous animals eat only plants"); } } class Implement { static void Main(string[] args) { Carnivorous cn = new Carnivorous(); Herbivorous hn = new Herbivorous();

cn.FoodHabits(); hn.FoodHabits(); } }In the preceding code example, the abstract method is declared by adding the abstract modifier to the method. Abstract method FoodHabits() is declared in the abstract class Animal. And then the abstract method is inherited in Carnivorous and Herbivorous class. Abstract methods cannot contain any method body.

Page 118: C#

Using Virtual Functions

When you have a function defined in a class which you want to allow to be implemented by the inherited classes, you can use virtual function could be implemented by the inherited classes on their own way and the call to the method is decided at runtime.

The following code is an example of using virtual function:

using System;namespace VirtualFunction{ class Animal { public virtual void FoodHabits() { Console.WriteLine("Animals have different food habits"); } } class Carnivorous : Animal { public override void FoodHabits() { Console.WriteLine("The Carnivorous animals eat only meat"); } } class Herbivorous : Animal { public override void FoodHabits() { Console.WriteLine("The Herbivorous animals eat only plants"); } } class Implement { public void callFunction(Animal Cr) { Cr.FoodHabits(); } } class ClassMain { static void Main(string[] args) { Implement Imp = new Implement(); Carnivorous cn = new Carnivorous(); Herbivorous hn = new Herbivorous(); Imp.callFunction(cn); Imp.callFunction(hn); Console.ReadLine(); } } }

Page 119: C#

In the preceding code, the base class named Animal has a virtual function named FoodHabits. The derived classes Carnivorous and Herbivorous override the method FoodHabits of the base class Animal and implement their own functionality. The method named callFunction takes and argument of Animal class and calls FoodHabits() method to, which in turn will call the most appropriate derived method.

Using Sealed Classes

There may be times when you do not need a class to be extended. You may even want to deliberately force users not to inherit a class. You could restrict users from inheriting the class by sealing the class using the sealed keyword. The keyword tells the compiler that the class is sealed, and therefore, cannot be extended. No class can be derived from a sealed class. The following is a example of a sealed class.

sealed class FinalClass { private int x; public void Method1() { } }

The method can also be sealed, and in that case, the method cannot be overridden. The following is an example of using sealed method in a sealed class:

sealed class FinalClass { private int x; public sealed void Method1() { } }

Using Interfaces

An interface defines the syntactical contract that all the derived classes should follow. Specifically the interface defines what part of the syntactical contract, and the classes implementing the interface describe the how part of the contract. C# has full support for interfaces.

Interfaces also define properties, methods, and events which are known as members of the interface. It is important to note that interfaces contain only the declaration of members. Classes and structures implement these interface members. Interface is used when you want to standard structure of methods to be followed by the classes, where classes will implement the functionality. Whereas, abstract classes are used in the situation where you want only few methods to declare by the base class and the derived class will implement the functionality.

Interfaces enable you to separate the definition of objects from their implementation so that the objects can evolve without the risk of introducing incompatibility in existing application.

Working with Interfaces

Working with interfaces includes interface declaration and implementation of interface by the classes.

Page 120: C#

Declaring Interfaces

You can declare interfaces using the interface keyword. The declaration of interfaces is very similar to class definition. Interface statements are public by default. The following code is an example of an interface declaration:

public interface IOrderDetails { //Declare an interface member void UpdateCustStatus(); void TakeOrder(); }

You can declare only methods, functions, and properties in interfaces. You cannot declare a variable in interfaces.

Implementing Interfaces

Interfaces declare methods, which are implemented by classes. A class can inherit from single class but can implement from multiple interfaces. The following code is an example of interface implementation:

public interface IOrderDetails { //Declare an interface member void UpdateCustStatus(); void TakeOrder(); } public class ItemsDetails : IOrderDetails { public void UpdateCustStatus() { .... } public void TakeOrder() { .... } }

Interfaces can inherit members from an existing interface. The class which implements from an interface needs to implement all the members of the interface.

Inheriting Interfaces

The following code shows how interfaces inherit from the existing interface:

public interface Validate_Cust { void Validate_Custname(); } public interface IOrderdetails : Validate_Cust { void UpdateCustStatus(); }

Page 121: C#

A class or a structure that implements interfaces also implements the base interface of it inherited interface. In the preceding example, the IOrderDetails interface inherits the member, Validate_Custname(), from the base interface, Validate_Cust. If a class implements the IOrderDetails interface, then it implicitly implements the Validate_cust interface.

Activity: Order-Processing System Using Abstract Classes

Problem Statement

Furniture and Fitting Company (FFC) manufactures domestic furniture. Customers provide their specifications to the company for the furniture they want. To cope with the received customer’s orders, FFC decides to computerize the order-processing system. The system should accept the values of furniture items, such as bookshelf and a chair. You need to to develop the hierarchy of these items.

Solution

To develop the required application, Time needs to perform the following tasks:1. Create a console based application2. Build and execution an application.

Task 1: Creating a Console-Based Application

1. Select Start All Programs Microsoft Visual Studio 2005 Microsoft Visual Studio 2005. The Start Page – Microsoft Visual Studio window will be displayed

2. Select File New Project. The New Project dialog box will be displayed3. Select the project type as Visual C# from the Project types pane and Console

Application from the Templates pane.4. Type the name of the new project as FFC in the Name text box.5. Specify the location where the new project is to be created as c:\chapter8\Activity1 in

the Location combo box.6. Click the OK button.7. Open the Solution Explorer window and right-click the Program.cs file.8. Select the Rename option and type the new name as Furniture.cs9. Double-click the Furniture.cs file in the solution explorer window. The code view of

the Furniture.cs file is displayed10. Replace the existing code with the following code:

using System;namespace FFC{ public abstract class Furniture { protected string color; protected int width; protected int height;

public abstract void Accept(); public abstract void Display(); } class BookShelf : Furniture { private int numOf_shelves; public override void Accept()

Page 122: C#

{ string str2, str3, str4; Console.WriteLine("Enter values for Bookshelf"); Console.WriteLine("Enter color"); color = Console.ReadLine(); Console.WriteLine("Enter Width"); str2 = Console.ReadLine(); width = Convert.ToInt32(str2); Console.WriteLine("Enter Height"); str3 = Console.ReadLine(); height = Convert.ToInt32(str3); Console.WriteLine("Enter No. Of Shelves"); str4 = Console.ReadLine(); numOf_shelves = Convert.ToInt32(str4); } public override void Display() { Console.WriteLine("DISPLAYING VALUES FOR BOOKSHELF"); Console.WriteLine("Color is {0}", color); Console.WriteLine("Width is {0}", width); Console.WriteLine("Height is {0}", height); Console.WriteLine("Number of Shelves is {0}", numOf_shelves); } } class Chair : Furniture { private int numOf_legs; public override void Accept() { string str2, str3, str4; Console.WriteLine("ENTER VALUES FOR CHAIR"); Console.WriteLine("Enter color"); color = Console.ReadLine(); Console.WriteLine("Enter Width"); str2 = Console.ReadLine(); width = Convert.ToInt32(str2); Console.WriteLine("Enter Height"); str3 = Console.ReadLine(); height = Convert.ToInt32(str3); Console.WriteLine("Enter No. Of legs in a chair"); str4 = Console.ReadLine(); numOf_legs = Convert.ToInt32(str4); } public override void Display() { Console.WriteLine("DISPLAYING VALUES FOR CHAIR"); Console.WriteLine("Color is {0}", color); Console.WriteLine("Width is {0}", width); Console.WriteLine("Height is {0}", height); Console.WriteLine("Number of legs is {0}", numOf_legs); } } class BookShelfChair { static void Main(string[] args) {

Page 123: C#

BookShelf b1 = new BookShelf(); Chair c1 = new Chair(); b1.Accept(); b1.Display(); c1.Accept(); c1.Display(); Console.ReadLine(); } }}

Task 2: Building and Executing an Application

To build and execute the application perform the following steps:1. Build the solution by pressing Ctlr + Shift +b2. Select Debug Start Debugging or press F5 to execute the application3. Verify the output of the application

Practice Questions

1. Consider the following statements

Statement A : Inheritance reduces the redundancy in codeStatement B : Inheritance enables easy maintenance of code.Which of the following is true about the given statements

a. Statement A is true, and Statement B is falseb. Statement A is false, and Statement B is truec. Both Statements A and B are trued. Both Statements A and B are false.

2. Consider the following codea. Void c() and void d()b. Void a() and void b()c. Void a(), void b(), void c() and void d()d. Void a(), void c() and void d()

3. Which of the following is true about abstract classes?a. An abstract class defines the properties common to the classes derived from it.b. An abstract class can be declared as finalc. Abstract classes cannot be extendedd. Classes declared using the abstract keyword can be instantiated.

4. Consider the following code:

interface a { void b(); } class c { void a.b() { }

}Which of the following statement generates the compilation error in the preceding code?

Page 124: C#

a. Interface ab. Void b()c. Void a.b() {}d. Class c

5. Consider the following statements:

Statement A: A class cannot have more than one derived class.Statement B: Inheritance increases the functionality of a base class by adding additional features to its derived classes.Which of the following statement is true?

a. Statement A is true, and Statement B is falseb. Statement A is false, and Statement B is truec. Both Statements are trued. Both Statements are false.

Summary

In this chapter, you learned that: The four kinds of relationships that exists among classes are:

o Inheritance relationshipo Composition relationshipo Utilization relationshipo Instantiation relationship

OOP enables classes to inherit commonly used state and behavior from other classes. Generalization means that multiple classes can inherit from the same superclass. The composition relationship exists when one class is made up of another class. The utilization relationship exists between 2 or more unrelated classes if one class uses

the other. An instantiation relationship is a relationship between a class and an instance of that

class. A class that inherits or derives attributes from another class is called the derived class

and the class from which it is derived is called the base class. Inheritance avoids redundancy in code and enables easy maintenance of code. Constructors are called in the order of base-to-derived. An abstract superclass is a conceptual class that does not exist in real world but acts as

a base from which other classes inherit properties behavior A sealed class tells the compiler that the class cannot be extended further. You cannot

derive a class from a sealed class. An interface defines properties, methods, and events. The properties, methods, and

events that are defined in the interface are known as the members of the interface.

Exercises

Exercise 1

Philip Anderson is a software developer who works for Mega Technnologies. He is currently under the project of geometric calculations. Philip has to develop a program, which performs the following tasks:

1. Calculate the area of the circle2. Calculate the volume of the cube

He has to develop the code using an interface

Page 125: C#

Exercise 2

Samuel Smith a student of California university is currently pursuing Bachelors in Information Technology (IT). Samuel has got an assignment to develop a program using the abstract classes, which displays the following statements:

1. I’m a line2. I’m a circle3. I’m a square

He has to create a Draw() function in a program, to display the preceding statements

Chapter 9

File Input and Output

For information to be saved permanently on a disk, you can use a file. The file is a stream of characters or a flow of related data. Streams enable you to write and read bytes to and from a storage medium, respectively. Streams can be used to perform fundamental operations such as read and write.

This chapter introduces the concept of the file input and output operations. It explains the process of reading and writing in the text files ad the binary files. It also explains the process of browsing through the Windows File System.

Objectives

In this chapter, you will learn to: Implement the file input and output operations Implement read and write in text files Implement read and write in binary files Implement the Windows File System

Implementing the File Input and Output Operations

All programs accept input from a user, process the input, and produce an output. Therefore, all the programming languages support the input and output operations. For information to be saved permanently on a disk, you can use a file. The file is a collection of data stored on a disk with a specific name and very often with a directory path. When you open the file for reading data or writing data, it becomes a stream.

The stream is a sequence of bytes traveling from a source to a destination over a communication path. The two basic streams used are the input and output streams. Each stream has a particular function. An input stream is used for a read operation and an output stream is used for performing a write operation. You can perform both these operations over the stream.

The System.IO namespace includes various classes, which are used to perform operations, such as file creation, file deletion, and read-write operations to files.

The following table describes some commonly used classes in the System. IO namespace.

Class Name DescriptionFileStream Is used to read from and write to any location within a fileBinaryReader Is used to read primitive data types from a binary stream

Page 126: C#

BinaryWriter Is used to write primitive data types in a binary formatStreamReader Is used to read characters from a byte stream StreamWriter Is used to write characters to a streamStringReader Is used to read from string bufferStringWriter Is used to write into a string bufferDirectoryInfo Is used to perform operations on directoriesFileInfo Is used to perform operations on files

In .NET, you can work with streams by using the FileStream class. This class supports random access to files, which means to read from and write to any location within a file.

FileStream Class

Most file Input/Output (I/O) support in the .NET Framework is implemented in the system.IO namespace. You can use the FileStream class in the System.IO namespace to read from, to write and to close files. This class inherits from the abstract class Stream. Many of its properties and methods are also derived from the Stream class.

To open an existing file or to create a new file, you need to create an object of type FileStream. Consider the following syntax for creating the object of type FileStream:

FileStream <object name> = new FileStream(<File Name>, <FileMode Enumerator>, <File AccessViolationException Enumerator>, <FileShare Enumerator>);

Consider the following example of creating the object of type FileStream:

FileStream File1 = new FileStream("MyFile.Txt", FileMode.Open, FileAccess.Read, FileShare.Read);

In the preceding example, the FileMode, FileAccess and FileShare enumerations define constants that are used by some of the FileStream and the IsolatedStorageFileStream constructors and some of the File.Open overloaded methods. These constants affect the way in which the underlying file is created, opened and shared

FileMode Enumerator

This enumerator defines various methods for opening files. The FileMode enumerator parameter is specified in many constructors for the FileStream, IsolatedStorageFileStream constructors, and in the Open methods of File and FileInfo to restrict how a file is opened. The parameters to FileMode checks whether a file is overwritten, created, or opened.

The members of the FileMode enumerator are: Append: Opens the file if it exists and places the cursor at the end of file, or creates a

new file. Create: Creates a new file CreateNew: Specifies to an operating system that it should create a new file Open: Opens an existing file OpenOrCreate: Specifies to the operating system that it should open a file if it exists;

otherwise, it should create a new file. Truncate: Opens an existing file. When opened, the file should be truncated so that its

size is zero bytes.

FileAccess Enumerator

Page 127: C#

Unless you specify a FileAccess enumerator, the file gets opened for both reading and writing. This enumerator indicates whether you want to read data from the file, write to the file, or perform both the operations.

The members of the FileAccess enumerator are Read, ReadWrite, and Write.

FileShare Enumerator

The FileShare enumerator contains constants for controlling the kind of access that the other FileStream constructors can have to the same file. A typical use of this enumeration is to define whether two different applications can simultaneously read from the same file.

The members of the FileShare enumerator are: Inheritable: Allows a file handle to pass inheritance to the child processes. None: Declines sharing of a current file Read: Allows opening of a file for reading purposes ReadWrite: Allows opening a file for the purpose of reading and writing Write: Allows opening of a file for writing purpose.

Implementing Reading and Writing in the Text Files

The Stream class is used to read from and to write data in the text files. It is an abstract class, which supports reading and writing bytes into it. If data of a file in only text, then you can use the StreamReader class and the StreamWriter class to accomplish the reading and writing tasks, repectively.

StreamReader Class

The StreamReader class is inherited from the abstract class TextReader. The TextReader class represents a reader which can read a series of characters.

The following code implements the StreamReader class:

FileStream fs = new FileStream("Myfile.txt", FileMode.Open, FileAccess.Read);

StreamReader sr = new StreamReader(fs); sr.BaseStream.Seek(0, SeekOrigin.Begin); string str = sr.ReadLine();

In the preceding code, the Seek() method allows the read/write position to be moved to any position within the file. This method takes two parameters, a byte position and a reference point. The byte position is relative is relative to the reference point. The reference point can be Begin, Current, or End. These reference points are represented by the properties of the SeekOrigin class.

The reference point, Begin, provides the seek reference position as the beginning of the stream. Current provides the seek reference position as the current position within the stream and the reference point. End, provides the seek reference position as the end of the stream. The objects f the FileStream class are used to provide random access to files. The FileStream constructor takes parameters that are used to initialize the member of the class.

Page 128: C#

The following table describes some of the commonly used methods of the StreamReader class.

Methods DescriptionClose Closes the object of StreamReader class and the userlying stream, and

releases any system resources associates with the readerPeek Returns the next available character but does not consume itRead Reads the next character or the next set of characters from the streamReadLine Reads a line of characters from the current stream and returns data as a

stringSeek Allows the read/write position to be moved to any position within the file.

The following code snippet implements the StreamReader class the read data from the file:

using System;using System.IO;class FileRead { public void ReadData() { FileStream fs = new FileStream("Myfile.txt", FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fs); //Position the file pointer at the beginning of the file sr.BaseStream.Seek(0, SeekOrigin.Begin); //Read till the end of the file is encountered string str = sr.ReadLine(); while (str != null) { Console.WriteLine("{0}", str); str = sr.ReadLine(); } //Close the writer and underlying file sr.Close(); fs.Close(); } public static void Main(string[] args) { FileRead fr = new FileRead(); fr.ReadData(); } }

StreamWriter Class

The StreamWriter class is inherited from the abstract class TextWriter. The TextWriter class represents a writer, which can write a series of characters.

The following table describes some of the commonly used methods of the StreamWriter class.Methods DescriptionClose Closes the current StreamWriter object and the underlying stream.Flush Clears all buffers for the current writer and causes any buffered data to be

written to the underlying stream

Page 129: C#

Write Writes to the streamWriteLine Writes data specified by the overloaded parameters, followed by end of line.The following code implements the StreamWriter class to accept data from a user and write the same into the file.

using System;using System.IO;class FileWrite { public void WriteData() { // Object of filestream class is created FileStream fs = new FileStream("Myfile.txt", FileMode.Append, FileAccess.Write); StreamWriter w = new StreamWriter(fs); //Prompting user to enter the string which needs to be stored in the file Console.WriteLine("Enter a string"); //Reads the string entered by the user and stores in str string str = Console.ReadLine(); //Write the string entered by the user in the file Myfile.txt w.Write(str) //Clears all buffer of the current writer w.Flush(); //Close the current StreamWriter Object. w.Close(); fs.Close(); } public static void Main(string[] args) { FileWrite fw = new FileWrite(); fw.WriteData(); } }

In the preceding code, the FileMode property value is Append and the FileAccess property value is Write. This opens the file, Myfile.txt, in the append mode and prepares the stream for a write operation. The statement, StreamWriter w = new StreamWriter(fs), creates a new instance of the StreamWriter class for MyFile.txt.

In addition, code accepts input from a user and writes the contents to Myfile.txt. the functions that can be used for the write operations are Write() and WriteLine(). The difference between Write() and WriteLine() operations is that the Write() method is WriteLine() method is used to display the information followed by a line terminator.

The Flush() methods clears the stream buffer. The Close() method closes the stream and releases any resources associated with the current stream.

Implementing Reading and Writing in Binary Files

All the information stored in the text format would be displayed on a screen as text. This means ‘A’ will be written as ‘A’ in the files. Similarly, the number -12345.678 will be written as the string “-12345.678”. This means that you can directly display the contents of the file on the screen.

Page 130: C#

Binary read and write means that the number -12345.678 is written as a float representation consuming four bytes of space. The BinaryReader and BinaryWriter classes are used for reading and writing the binary data in to files.

BinaryReader Class

The BiinaryReader class is used to read binary data from a file. You can create BinaryReader object by passing its constructors, a FileStream object, as shown in the following code snippet:

FileStream fs = new FileStream(@"C:\TEST2.DAT", FileMode.Open, FileAccess.Read);BinaryReader br = new BinaryReader(fs);

The following table describes some of the commonly used methods of the BinaryReader class.

Method DescriptionClose Closes the current reader and the underlying streamRead Reads characters from the underlying stream and advances the current position of

the stream.

BinaryWriter Class

The BinaryWriter class is used to write binary data to a stream. You can create a BinaryWriter object by passing its constructors, a FileStream object as shown in the following code snippet:

FileStream fs = new FileStream(@"C:\TEST2.DAT", FileMode.CreateNew);BinaryWriter br = new BinaryWriter(fs);

The following table describes some of the commonly used methods of the BinaryWriter class.

Method DescriptionClose Closes the current BinaryWriter and the underlying streamSeek Sets the position within the current streamWrite Writes a value to the current streamFlush Clears all buffers for the current writer and causes any buffered data to be written to

the underlying device.

The following ode snippet shows the implementation of the Binary Reading and Writing classes to a file:

using System;using System.IO;namespace BinaryData{ public class RWData { public static void Main(string[] args) { BinaryWriter dataout; BinaryReader datain;

int i = 10; double d = 1023.56; bool b = true; try

Page 131: C#

{ dataout = new BinaryWriter(new FileStream("testdata", FileMode.Create)); } catch (IOException exc) { Console.WriteLine(exc.Message + "\nCannot open file."); return; } try { Console.WriteLine("Writing" + i); dataout.Write(i); Console.WriteLine("Writing" + d); dataout.Write(d); Console.WriteLine("Writing" + b); dataout.Write(b); Console.WriteLine("Writing" + 12.2 * 7.4); dataout.Write(12.2 * 7.4);

} catch (IOException exc) { Console.WriteLine(exc.Message + "\n Write error."); } dataout.Close(); Console.WriteLine();

//Now, read them back. try { datain = new BinaryReader(new FileStream("testdata", FileMode.Open)); } catch (FileNotFoundException exc) { Console.WriteLine(exc.Message + "\n Cannot open file."); return; } try { i = datain.ReadInt32(); Console.WriteLine("Reading" + i); d = datain.ReadDouble(); Console.WriteLine("Reading" + d); b = datain.ReadBoolean(); Console.WriteLine("Reading" + b); d = datain.ReadDouble(); Console.WriteLine("Reading" + d); } catch (IOException exc) { Console.WriteLine(exc.Message + "Read error."); } Console.ReadLine(); datain.Close(); }

Page 132: C#

}}

Implementing the Windows File System

The ablity to browse and locate files and directories for a specific directory is essential for many programming tasks. You can work with files and directories by using classes such as the DirectoryInfo and FileInfo classes in combination. Using these classes is an efficient way to gather the required information about files and directories in a specific location.

DirectoryInfo

The DirectoryInfo class is derived from the FileSystemInfo class. The following table describes some of the commonly used properties of the DirectoryInfo class.

Property DescriptionAttributes Gets or sets attributes associated with the current file. This property

is inherited from FileSystemInfo.CreationTime Gets or sets CreationTime of the current file. This property is

inhertied by FileSystemInfoExists Gets a boolean value indicating whether the directory exists or not.Extension Gets a string containing the file extension. This property is inherited

from FileSystemInfoFullName Gets a string containing the full path of the directory. . This property

is inherited from FileSystemInfoLastAccessTime Gets the last accessed time of the directory. This property is

inherited from FileSystemInfoName Gets a string containing the name of a given file.

The following table describes the most commonly used methods of the DirectoryInfo class.

Method DescriptionCreate Creates a directoryCreateSubdirectory Creates a subdirectoryDelete Deletes a directoryGetDirectories Returns the directories in the current directory after watching all the criteria.

It also allows you to search subdirectories within directoriesGetFiles Returns the files in the current directory

The following code snippet shows how to create a DirectoryInfo object:

DirectoryInfo MydirInfo = new DirectoryInfo(@"C:\WINDOWS");Console.WriteLine("FullName of the directory is {0}", MydirInfo.FullName);Console.WriteLine("The directory was last accessed on {0}", MydirInfo.LastAccessTime.ToString());

The preceding code snippet creates the DirectoryInfo object by the name MydirInfo. The code snippet displays the full path to the directory and the time when the directory was last accessed.

FileInfo Class

The FileInfo class is derived from the FileSystemInfo class. The following table describes the most commonly used methods of the FileInfo class.

Page 133: C#

Property DescriptionAttributes Gets or sets attributes associated with the current file. This property is

inherited from FileSystemInfo.CreationTime Gets or sets CreationTime of the current file. This property is inhertied by

FileSystemInfoDirectory Gets an instance of the directory which the file belongs toExists Gets a Boolean value indicating whether the file exists or notExtension Gets a string containing the file extension. This property is inherited from

FileSystemInfoFullName Gets a string containing the full path of the file. . This property is inherited

from FileSystemInfoLastAccessTime Gets the last accessed time of the file. This property is inherited from

FileSystemInfoLastWriteTime Gets the time of the last written activity to the file. . This property is inherited

from FileSystemInfoLength Gets the size of the fileName Gets a string containing the name of a given file

The following table lists some of the commonly used methods of the FileInfo class and their functions.

Method FunctionCreate Creates a directoryAppendText Appends a text to the file represented by the FileInfo objectDelete Deletes a fileOpen Opens fileOpenRead Opens a file in read-only mode

The following code shows the use of the FileInfo class:

using System;using System.IO;namespace File_Handling{ class Tester { public static void Main(string[] args) { //Creating an instance of DirectoryInfo class DirectoryInfo MydirInfo = new DirectoryInfo(@"C:\WINDOWS"); //get all the files in the directory and //print their name, and size FileInfo[] FilesInDir = MydirInfo.GetFiles(); foreach (FileInfo file in FilesInDir) { Console.WriteLine("File Name: {0} Size: {1} bytes", file.Name, file.Length); } } }}

Page 134: C#

In the preceding code, the GetFiles() method is used to retrieve the list of all the files in the directory. This code displays the list of all the files the directory and their sizes.

Practice Questions

1. Which method in the following code writes the input to the stream?a. String str = Console.ReadLine();b. Sw.Write(Str);c. Sw.Flush();d. Sw.Close();

2. You need to access a file named MyFile.txt. If the file already exists on the system, you need to open it; else you need to ensure that a new file with the file name MyFile.txt is created. Which of the following statements would you write to do the preceding task?

a. FileStream Fs = new FileStream(“c:\\MyFile.txt”, FileMode.Create, FileAccess.Write);

b. FileStream Fs = new FileStream(“c:\\MyFile.txt”, FileMode.CreateNew, FileAccess.Write);

c. FileStream Fs = new FileStream(“c:\\MyFile.txt”, FileMode.Open, FileAccess.Write);

d. FileStream Fs = new FileStream(“c:\\MyFile.txt”, FileMode.OpenOrCreate, FileAccess.Write);

3. The method that is used to alter the positions from where a read and write operation can occur is ______

4. Match the following terms in column B to the description in column A

A BAttribute Gets or sets CreationTime of the current fileCreationTime Gets a Boolean value indicating whether the directory exists or notExits Gets or sets attribute associated with the current file. This property is

inherited from FileSystemInfo

5. John wants to perform a read/write operation on a file. He does not want the file to be overwritten when he is performing the write operation. Which FileMode should he use?

Summary

In this chapter, you have learned that: A stream is an abstraction of a sequence of bytes traveling from a source to a destination

over a communication path. The two basic streams used are the input and output streams. An input stream is used for

a read operation and an output stream in used for performing a write operation Most file I/O support in .NET Framework is implemented in the System.IO namespace.

You can use the FileStream class in the System.IO namespace to read from, to write and to close files.

The FileStream class inherits from the abstract class Stream. The Stream class is used to read and write data to the text files. It is an abstract class,

which supports reading and writing bytes into it. The StreamReader class is inherited from the abstract class TextReader. The

TextReader class represents a reader which can read a series of characters. The StreamWriter class is inherited from the abstract class TextWriter. The TextWriter

class represents a writer which can write a series of characters.

Page 135: C#

The BinaryReader class allows reading of binary data from a file. The BinaryWriter class allows writing of binary data to a stream. The DirectoryInfo class is derived from FileSystemInfo class and its works on a specific

directory and shows the fullpath of the current directory The FileInfo class is derived from FileSystemInfo class and its works on a specific

directory to display the list of all the files.

Exercises

Exercise 1

David is a team leader of xyz organization. He wants to create a scheduler, which will store fields, such as the appointment date, the name of the person to meet, and time. He needs to develop an application that will enable the user to fill these fields.

The application should display certain options. The options are: Add appointment: Should accept values such as appointment date, name of the person

to be met, and time of the appointment. View appointment: Should display all the appointments of the user Search: Should prompt the user to specify the date to view all the appointments of that

day Exit: Allow the user to exit the application

Hint: The date that the application should accept should be in the mm/dd/yyyy format.

Exercise 2

You need to generate a program to play the Hangman game. The program asks a user to enter a category as Book or Movie. Based on the category provided, a book name or movie name is extracted and the user is asked to guess the name by giving the character and its position in the string.

Chapter 10

Exception Handling

An exception is termed as an abnormal condition encountered by an application during execution. Exception handling is the process of providing an alternative path of execution when the application is unable to execute as desired.

This chapter describes exceptions. It explains how to implement the try, catch and finally blocks. In addition, it also discusses the implementation of user-defined exceptions.

Objectives

In this chapter, you will learn to Describe exceptions Handle exceptions Implement the user-defined exceptions

Describing Exceptions

An exception is an erroneous situation that occurs during program execution. Exceptional situations arise when an operation cannot be executed normally. When an exception occurs in an

Page 136: C#

application, the system throws an error. The error is handled through the process of exception handling.

For example, the System.IO.IOException error is thrown when you try to access an illegal stream object. Similarly, if the denominator is zero, an integer division operation throws the System.DivideByZeroException error.

Whenever an error occurs, runtime creates an exception object and sends it to the program in which the exception occurred. This action is known as throwing an exception. The exception object contains information about the type of error.

Types of Errors

There are 3 types of errors that can occur in the applications. These are: Syntax errors Run-time errors Logical errors

A syntac error occurs when compiler cannot compile code. Such an error can occur when statements are not constructed properly, keywords are misspelled, or punctuation is omitted. At compilation time all the statements in the application get connected with each other to make a single executable unit.

A run-time error occurs when an application attempts to perform an operation, which is not allowed at runtime. An example of such an error is division by zero. A run-time error is also termed as an exception. All the exceptions are defined in the predefined set of classes.

A logical error occurs when an application compiles and runs properly but does not produce the expected results.

All the exceptions are derived from the System.Exception class, which is the parent class of all exceptions.

Exception Classes

There are many exception classes which are directly or indirectly derived from the System.Exception class. Some of the exception classes derived from the System.Exception classes are the System.ApplicationException and System.SystemException classes

The hierarchy of the exception classes is displayed in the following figure

Page 137: C#

The System.ApplicationException class is forwarded by a user program, and not by the CLR. If any user-defined application requires its own exception, it should inherit the exception from the ApplicationException class.

The System.SystemException acts as a base class for all the predefined system exceptions. The following table describes some of the classes derived from the System.SystemException class.

Exception Classes DescriptionsSystem.IO.IOException Handles I/O errorsSystem.IndexOutofRangeException Handles errors generated when a method to refers

to an array element, which is out of its boundSystem.NullReferenceException Handles errors generated during the process of

dereferencing a null objectSystem.DivideByZeroException Handles errors generated during the process of

dividing the divided with zeroSystem.InvalidCastException Handles errors generated during typecastingSystem.OutOfMemoryException Handles memory allocation to the application

errors.

Handling Exceptions

You need to handle an exception in your program by using an exception-handler. This handler processes the exception. In exception handling, the application is divided into blocks of code. A block that shows the probability of raising an error contains one or more exception handlers. These handlers follow a control structure and a uniform way of handling the system level and application level errors.

The following example shows an exception is a variable is divided by zero:

using System;namespace System_Exception{ class Add_Num { public static void Adding_Numbers(int number1, int number2) {

System.Exception

System.ApplicationException

System.SystemnException

Page 138: C#

int res = number1 / number2; Console.WriteLine(res); } static void Main(string[] args) { Add_Num.Adding_Numbers (10,0) Console.ReadLine(); }

}}

The preceding code generates the DivideByZeroException.

The DivideByZeroException is thrown when an integer value is divided by zero. In the preceding code, when the program tries to execute a division by the zero statement, it results in a run-time error. The program has not been guarded for exceptions; therefore the default exception-handler is invoked. The default exception-handler displays the error message and allows you to troubleshoot the problem. If you do not want to troubleshoot the problem then you can terminate the program.

C# provides the structured solution to error-handling problems in the form of try and catch blocks. Using these blocks the core program statements can be separated from the error-handling statements. The core program statements handle normal program flow. You can also use the finally block to handle errors.

These blocks for exception handling can be implemented using the following keywords: Try Catch Finally

The try Block

The try block guards statements that may throw an exception.try { //Statements that may cause an exception }

The try block governs statements that are enclosed within it and defines the scope of the exception-handlers associated with it. In other words, if an exception occurs within the try block, an appropriate exception-handler that is associated with the try block handles the exception. A try block must have atleast one catch block.

The Catch Block

You can associate an exception-handler with the try block by providing one or more catch handlers, immediately after the try block.

try { //Statements that may cause an exception } catch(....) { //error handling code

Page 139: C#

}The catch statement of the catch block takes an object of the exception class as a parameter, which refers to the raised exception. When the exception is caught, the statements within the catch block are executed. The following code illustrates the use of a catch block:

using System;using System.IO;namespace Add_Nums{ class AddNumbers { public static void Adding_Numbers(int number1, int number2_ { try { int res = number1/number2; Console.WriteLine(res); } catch(DivideByZeroException e) //Exception Handler { Console.WriteLine("Exception Caught. {0}", e); } // This executes after the catch block Console.WriteLine("After handling the exception"); } static void Main(string[] args) { AddNumbers.Adding_Numbers(10,0); Console.ReadLine(); }

}}

The Finally Block

The finally block is used to execute a given set of statements, whether an exception is thrown or not thrown. For example, a file has to be closed whether an exception is raised or not. You can place code to close the file in both the try and catch blocks:

try { //Statements that may cause an exception } catch(....) { //error handling code }

finally { //statements to be executed }

The catch block is used to handle exceptions that occur in a try block. The finally block is used to guarantee the execution of statements, regardless of whether an exception has occurred or not

Page 140: C#

occurred. You can have only one finally block for each try block. It is however not mandatory to have a finally block after a try block.

Consider the following code, which shows the use of the finally block:

using System;using System.IO;namespace Add_Nums{ class AddNumbers { int result; AddNumbers() { result = 0; } public void Divide(int number1, int number2) {

try { result = number1 / number2; } catch (DivideByZeroException e) { Console.WriteLine("Exception Caught. {0}", e); } finally { Console.WriteLine("Result is {0}", result); } Console.WriteLine("After handling the exception"); } static void Main(string[] args) { AddNumbers Division = new AddNumbers(); Division.Divide(10.0); Console.ReadLine(); }

}}

If the preceding code is modified with the positive values Divide(4,2), then the output is:

Result is 2.

Therefore code will not raise an exception.

Activity: Handling Exception for Arrays Beyond Limit

Problem Statement

David is working on a project where he is calculating the sum of values in an integer array. David needs to handle the exceptions, which can occur while he is working with the arrays. If any exceptional condition

Page 141: C#

is reached when David is executing the application, the application needs to display an exception message.

Help David to handle the exceptions.

Solution

To develop the required application, Time needs to perform the following tasks:1. Create a console based application2. Build and execution an application.

Task 1: Creating a Console-Based Application

1. Select Start All Programs Microsoft Visual Studio 2005 Microsoft Visual Studio 2005. The Start Page – Microsoft Visual Studio window will be displayed

2. Select File New Project. The New Project dialog box will be displayed3. Select the project type as Visual C# from the Project types pane and Console

Application from the Templates pane.4. Type the name of the new project as ArrayException in the Name text box.5. Specify the location where the new project is to be created as c:\chapter9\Activity1 in

the Location combo box.6. Click the OK button.7. Open the Solution Explorer window and right-click the Program.cs file.8. Select the Rename option and type the new name as ArrayOutofIndex.cs9. Double-click the ArrayOutofIndex.cs file in the solution explorer window. The code

view of the ArrayOutofIndex.cs file is displayed10. Replace the existing code with the following code:

using System;namespace ArrayException{ class ArrayOutOfIndex { public void CalculateSum() { int sum=0; int [] number = new int[5] {1,2,3,4,5);

try { for (int init = 1; init <=5; init++) { sum = sum + number[init]; } Console.WriteLine("The sum of the array is: {0}", sum); } catch (IndexOutOfRangeException e) { Console.WriteLine(e.Message); }

} } class ClassMain {

Page 142: C#

static void Main(string[] args) { ArrayOutOfIndex obj = new ArrayOutOfIndex(); obj.CalculateSum(); Console.ReadLine(); }

}}

Task 2: Building and Executing an Application

To build and execute the application perform the following steps:4. Build the solution by pressing Ctlr + Shift +b5. Select Debug Start Debugging or press F5 to execute the application6. Verify the output of the application

Implementing the User-Defined Exceptions

In C#, you can create your own exception class. Sometimes you may want to catch an exception, so some work to handle the exception, and then pass the exception on to the calling code. Such kinds of exceptions are known as the user-defined exceptions. The Exception must be base class for all the exceptions in C#. The user-defined exception classes must follow the hierarchy of either the exception class or of one of the standard inherited classes.

Creating the User-Defined Exceptions

User-Defined exception classes are derived from the ApplicationException class.

Consider the following example of user-defined exception named the CountIsZeroException exception:

using System;namespace UserDefineEx{ class CountZero { static void Main(string[] args) { Calculator calc = new Calculator(); try { calc.DoAverage(); } catch (CountIsZeroException e) { Console.WriteLine("CountIsZeroException: {0}", e.Message); } Console.ReadLine(); } } public class CountIsZeroException : ApplicationException {

Page 143: C#

public CountIsZeroException(string message) : base(message) { } } public class Calculator { int sum = 0; int count = 0; float average; public void DoAverage() { if (count == 0) throw (new CountIsZeroException("Zero count in DoAverage")); else average = sum / count; } }}

To implement user-defined exceptions you need to raise your exception and throw an object.

Raising your Own Exceptions

You can use the throw statement to raise your own exceptions, as shown in the following code:

public void DoAverage() { if (count == 0) throw (new CountIsZeroException("Zero count in DoAverage")); else average = sum / count; }In the preceding example, the throw statement is used to raise the user-defined exception, CountIsZeroException. If the value of count variable becomes zero while calculating the average; then the application raises the CountIsZeroException exception to notify a user that the value of the count variable is zero on the DoAverage() method.

Most of the time, exceptions expect either an appropriate message string as an input or a parameter when they are generated. The message can be displayed when the exception is picked.

Note:Never create and throw objects of class exception

Throwing objects

You can throw an object if the object is either directly or indirectly derived from System.Exception.

You can use a throw statement in the catch block to throw the present object, as shown in the following code:

catch (Exception caught) {

Page 144: C#

. . .throw caught

}

You can also throw a new exception of a different type, as shown in the following example:

catch (IOException caught) { . . .

throw new FileNotFoundException(filename) }

In the preceding example, IOException is used for trapping the file input-output exception. The object of the IOException class is used to store the information about the exception if it is raised. This information is lost when the exception is converted into the FileNotFoundException object. A better way to handle the exception is add new information while keeping the previous information, as shown in the following code:

catch (IOException caught) { . . .

throw new FileNotFoundException(filename, caught) }

A throw without any expression can only be used in the catch block. Such a throw reverts the exception that is currently being handled. Therefore, the following statement will generate identical results:

catch (OutOfMemoryException caught) { throw caught;) . . .catch (OutOfMemoryException) { throw;)

Practice Questions

1. The base class of all exceptions is ______2. The set of statements that need to be executed whether an exception is thrown or not

thrown is included in the ______ block.3. Can a try block have more than one catch holder?4. State whether the following statement is true or false:

A try block ensures that an exception is handled.

5. An attempt to divide by zero throws the _____ exception.

Summary

In this chapter, you learned that: An exception is an erroneous situation that occurs during program execution. There are 3 types of error that can occur in an application

o Syntax erroro Run-time erroro Logical error

Exception handling provides a structured and uniform way of handling system-level and application-level errors.

Exception handling is implemented using the following keywordso Try

Page 145: C#

o Catcho finally

Exception handling is the process of providing an alternative path to be executed when an application is not able to execute in a desired way

In addition to handling pre-defined exceptions, users can create their own exceptions by deriving an exception class from the ApplicationException clas.

You can only throw an object if the types of objects either directly or indirectly derives from System.Exception.

You can use the throw statement to raise your own exceptions.

Exercises

Exercise 1

David wants to create to ticket booking application for a movie theater. The application should ask the user for his choice, whether he wants to book the tickets or not. The application should also ask the user for the total number of tickets to be booked. While booking the tickets if the total number of booked tickets exceeds the available tickets, the application should raise an exception.

Hint: The total number of available tickets is ten.

Chapter 11

Creating Multithreaded Applications

A program executes as a single, sequential flow of control. A program can also be designed to execute multiple tasks. To execute multiple tasks in your program, you can use threads.

This chapter discusses implementation of threads and their life cycle. The chapter also discusses implementing multiple threads and prioritizing threads. In addition, this chapter discusses thread synchronization and communication between processes.

Objectives

In this chapter, you will learn to: Implement threads Define the life cycle of a thread Implement multiple threads Identify the thread priority Use synchronization in threads Identify communication between processes

Implementing Threads

A thread is defined as the execution path of a program. You can define a unique flow of a control in a program, using a thread. Threads are used to run applications that perform large and complex computations.

For example, a Central Processing Unit (CPU) performs various complex tasks simultaneously. The processes include tasks such as writing and printing a document, installing software, and displaying the date and time on the status bar. All these processes are handled by separate threads.

A process that is executed using one thread is knows as a single-threaded process, where the process is running instance of a program. A single-threaded application can perform only one

Page 146: C#

task at a time. You have to wait for one task to complete before another task can start. The following figure shows a single-threaded process.

To execute more than one task at a time, you can create multiple threads in a program. A process that creates two or more threads is called a multithreaded process. For example, any Web browser, such as Internet Explorer is a multithreaded application. Within the browser, you can print a page in the background while you scroll the page. Similarly, you can play audio files and watch animated images at the same time. Each thread in a multithreaded process runs at the same time and maintains a different execution flow.

The following figure shows a multithreaded process with two threads.

The Thread Model

A program uses threads to increase the efficiency of a CPU by preventing wastage of the CPU cycles. In the single-threaded systems, an approach called event loop with polling is used. Polling is the process in which a single event is executed at a time. In the event loop with polling approach, a single thread runs in an infinite loop till its operation is completed. When the operation is completed, the event loop dispatches control to the appropriate event handler. No more processing can happen in the system until the event-handler returns. This results in the wastage of the CPU time.

In a single-threaded application, if the thread is suspended from execution because it is waiting for a system resource, the entire program stops executing. This limitation can be overcome by using multithreading, which eliminates the event loop with polling approach. In multithreading, the time for which a thread waits for the CPU time can be utilized to perform another task.

In C#, you will use the Thread class to work with threads. The System.Threading.Thread class is used to construct and access individual threads in a multithreaded application. The first thread to be executed in a process is called the main thread.

The Main Thread

The main thread is created automatically on the start up of a C# program execution. The threads which are created exclusively using the Thread class are called as child threads, where the main thread is either called a parent thread or a primary thread.

Thread

ThreadTwo Threads

Page 147: C#

You can access a thread using the CurrentThread property of the Thread class.

The following code shows the execution of main thread using its CurrentThread property in the Thread class:

using System;using System.Threading;namespace ThreadExample{ class MainThreadExample { public static void Main(String[] args) { Thread Th = Thread.CurrentThread; Th.Name = "MainThread"; Console.WriteLine("The current thread after name change is: {0}", Th.Name); Console.ReadLine(); } } }

In the preceding code, a reference to the current thread is obtained by using the CurrentThread parameter of the Thread class and its reference is stored in the Th Variable. The Name parameter is used to set the name of the thread, and the information about the thread is displayed.

Working with Threads

In C#, you create a thread by creating an object of type Thread, giving its constructor a ThreadStart reference, and calling the new thread’s Start() method. The new thread starts executing asynchronously with an invocation of the thread’s method. When the method returns, the thread dies.

The other methods of the Thread class allow managing the lifetime of the thread and destroying the thread when required.

There are various methods available with the Thread class. Using these methods, you can control the execution of threads. Few of these methods are:

Start() : Starts a thread Sleep(): Makes the thread to pause for a period of time Abort(): Terminates the thread Suspend(): Suspends a thread. If the thread is already suspended it has no effect Resume(): Resumes the suspended thread.

Working with threads involves creating, managing, and destroying threads.

Creating Threads

You can create threads by extending the Thread class. The extended Thread class calls the Start() method to begin the child thread execution. You can use the following code to create a thread by extending the Thread class:

Page 148: C#

using System;using System.Threading;namespace ThreadSample{ class BasicThreadApp { public static void ChildThreadCall() { Console.WriteLine("Child Thread Started"); } public static void Main() { ThreadStart ChildRef = new ThreadStart(ChildThreadCall); Console.WriteLine("Main - Creating Child Thread"); Thread ChildThread = new Thread(ChildRef); ChildThread.Start();

Console.WriteLine("Main - Have requested the start of child thread"); Console.ReadLine(); } } }

In the preceding output, the Main() method prints before the message from the child thread proving that the child thread is indeed working asynchronously.

The first statement in the preceding code is the using statement for the System.Threading namespace. The first statement of the Main() method specifies the methid to be invoked by the thread:

ThreadStart ChildRef = new ThreadStart(ChildThreadCall);

The next statement instantiates a Thread object where the constructor takes the object of the ThreadStart class as its argument:

Thread ChildThread = new Thread(ChildRef);

Then the Start() method of the Thread object is called, and the method results in a call to the ChildThreadCall method. The extended Thread class calls the Start() method to begin the child thread execution.

Managing Threads

There are many tasks you might want to perform to manage the activity or life of a thread. You can manage all these tasks by using the various thread methods available with the Thread class.

For example, when you require the thread to pause for a period of time so that the thread is allowed to execute, you can call the Thread.Sleep() method. This method takes a single argument that represents time in milliseconds for which you want the thread to pause. This method is static method and cannot be called with an instance of a thread object. This is done to avoid a call to the Thread.Sleep() method on any other thread except the currently executing method.

Page 149: C#

The static Thread.Sleep() method calls the static CurrentThread method, which then pauses that thread for the specified amount of time. The following code shows the implementation of the Sleep() method:

using System;using System.Threading;namespace ThreadSample{ class BasicThreadApp { public static void ChildThreadCall() { Console.WriteLine("Child Thread Started"); int sleepTime = 5000;

Console.WriteLine("Sleeping for {0} seconds", sleepTime/1000); Thread.Sleep(sleepTime); //Sleep for 5 seconds Console.WriteLine("Waking up"); } public static void Main() { ThreadStart ChildRef = new ThreadStart(ChildThreadCall); Console.WriteLine("Main - Creating Child Thread"); Thread ChildThread = new Thread(ChildRef); ChildThread.Start();

Console.WriteLine("Main - Have requested the start of child thread"); Console.ReadLine(); } } }

There is more than one way to call the Sleep() method. One way is to call Thread.Sleep() with a value 0, which will cause the current thread to hand over the unused balance if its timeslice. The other way is to call Thread.Sleep() method with a value of Timeout.Infinite, which results in the thread being paused indefinitely until it is interrupted by another thread called the suspended thread’s Thread.Interrupt() method.

There is another method Thread.Suspend(), which is used to suspend the execution of a thread. The Thread.Suspend() method can be called on a currently executing thread or another thread. When a thread is suspended in this fashion, only another thread can cause its resumption, with the Thread.Resume() method. Notice, when a thread suspends another thread, the first thread is not blocked. The call returns immediately.

In addition, regardless of how many times the Thread.Suspend() method is called for a given thread, a single call to Thread.Resume() will cause the thread to resume execution.

Destroying Threads

If the thread is required to be destroyed, the Thread.Abort() method will allow you to accomplish the task. The runtime aborts the thread by throwing a ThreadAbortException. This exception

Page 150: C#

cannot be caught. If the finally block is present in the method, the runtime will send the control to it.

You can use the following code to destroy threads:

using System;using System.Threading;namespace ThreadSample{ class BasicThreadApp { public static void ChildThreadCall() { try { Console.WriteLine("Child Thread Started"); Console.WriteLine("Child Thread - counting to 10"); for (int i = 0; i < 10; i++) { Thread.Sleep(500); Console.WriteLine("{0}....", i); } Console.WriteLine("Child Thread finished"); } catch (ThreadAbortException e) { Console.WriteLine("Exception", e.Message); } finally { Console.WriteLine("Child thread - Unable to catch the exception"); } } public static void Main() { ThreadStart ChildRef = new ThreadStart(ChildThreadCall); Console.WriteLine("Main - Creating Child Thread"); Thread ChildThread = new Thread(ChildRef); ChildThread.Start(); // Give the child thread time to start Console.WriteLine("Main - Sleeping for 2 seconds"); Thread.Sleep(2000);

Console.WriteLine("Main - Aborting child thread"); ChildThread.Abort(); Console.ReadLine(); } } }

In the preceding code, the main() method pauses for 2 seconds to make sure that the runtime has had time to start the worker thread. When started, the worker thread starts counting to ten, pausing for a second in between each number. When the main() method resumes execution after

Page 151: C#

its 2 seconds pause, it aborts the worker thread. Notice the finally block is executed after the abort.

Implementing Thread Life Cycle

The life cycle of a thread starts when an object of the System.Threading.Thread class is created. The life cycle of the thread ends with the task execution. There are various states in the life cycle of a thread. These states are

The Unstarted state The Runnable State The Not Runnable State The Dead State

The following figure shows the various thread states and methods, which can cause the thread to move form one state to another.

The Unstarted State

When an instance of the Thread class is created, the thread enters the unstarted state.

A new thread is an empty object of the Thread class, and no system resources such as memory are allocated to it. You have to invoke the Start() method to start the thread.

The Runnable State

A thread remains in the unstarted state until the program calls the Start() method of the Thread class, which places the thread in the runnable state and immediately returns control to the calling thread. This state is also called as the ready or started state. The newly started thread and any other threads in the program execute concurrently.

A single processor cannot execute more than one thread at a time. Therefore, it maintains a thread queue. When a thread is started, a thread is queued up for the processor time and waits

Start( ) started

Work Complete

Stop( )

Sleep( )

Suspend suspend

Wait/Join Sleep

Stop Reg

Stoppedd

Time Expires

Thread respnds to stop request

Interrrupt ( )

Resume ( )

Page 152: C#

for its turn to get executed. As a result, the state of the thread is said to be runnable and not running.

The Not Runnable State

The thread is not the runnable state if it is: Sleeping: A thread is put into the sleeping mode by calling the Sleep() method. A

sleeping thread enters the runnable state after the specified time of sleep has elapsed. Waiting: A thread can be made to wait for some specified condition to be satisfied by

calling the Wait() method. The thread can be notified of the condition by invoking the Pulse() method of the Thread class.

Blocked: A thread could be blocked by an I/O operation. When the thread is blocked, it enters the not runnable state.

The Dead State

A running thread enters the dead state when the statements of the threads methods are complete. This state is called the terminated state. A program can force a thread into the dead state by calling the Abort() method of the Thread class on the appropriate thread object. The Abort() method throws a ThreadAbortException in the thread, normally causing the thread to terminate. When a thread is in the dead state and there are no references to the thread object, the garbage collector can remove the thread object from memory.

Activity: Hangman Game

Problem Statement

The next door children request you to create the Hangman Game for them. The game asks the user to enter a category as Book or Movie. Based on the category, a book name or movie name is extracted and the user is asked to guess the name of the game by giving the character and its position in a string. A user will get 60 seconds to play the game.

Develop the Hangman game application.

Solution

To solve the preceding problem, you need to perform the following tasks:

1. Identify the data source where the name of the book or movie is stored.2. Create a console-based application for the Hangman game3. Build and execute the application

Task 1: Identify the data source where the name of the book or movie is stored

To demonstrate the implementation of the Hangman game, you need to perform the following steps:

1. Identify the data source. The data source from where data needs to be retrieved is TextTest.txt.

2. Save the TextTest.txt in C drive.

Task 2: Create a console-based application for the Hangman game

To create a console based application for the Hangman game, you need to perform the following steps:

Page 153: C#

1. Select Start All Programs Microsoft Visual Studio 2005 Microsoft Visual Studio 2005. The Start Page – Microsoft Visual Studio window will be displayed

2. Select File New Project. The New Project dialog box will be displayed3. Select the project type as Visual C# from the Project types pane and Console

Application from the Templates pane.4. Type the name of the new project as HangmanApp in the Name text box.5. Specify the location where the new project is to be created as c:\chapter11\Activity1 in

the Location combo box.6. Click the OK button.7. Open the Solution Explorer window and right-click the Program.cs file.8. Select the Rename option and type the new name as Hangman.cs9. Double-click the Hangman.cs file in the solution explorer window. The code view of

the Hangman.cs file is displayed10. Replace the existing code with the following code:

/* Program to play Hangman game. The program asks a user to enter * a category as Book/Movie. Based on the category provided, a book name or category * name is extracted and the user is asked to guess the name by giving * the character and its position. */using System;using System.IO;using System.Threading;namespace Game{ public class Hangman { string randomString, userString; int dataLength; string Category; string[] bookData = new string[5]; string[] movieDate = new string[5]; int bookCount = 0, movieCount = 0; public Hangman() { FillNameValues(); } //Stores the movie names and Book names in respective strings private void FillNameValues() { // Declaring the variables

string firstLine; //open file for reading StreamReader sRead = new StreamReader("c:\\TestText.txt"); sRead.BaseStream.Seek(0, SeekOrigin.Begin); //Reading the content of the file firstLine = sRead.ReadLine(); while (firstLine != null) { //Storing the Book names in the Bookdata array if (firstLine.Substring(0, 1) == "B") { int stringStartPos = firstLine.IndexOf(':'); bookData[bookCount] = firstLine.Substring(stringStartPos + 1);

Page 154: C#

bookCount++; } //storing the Movie names in the MovieData array else { int stringStartPos = firstLine.IndexOf(':'); movieDate[movieCount] = firstLine.Substring(stringStartPos + 1); movieCount++; } firstLine = sRead.ReadLine(); } } public int AcceptCategory() { //Accepting the choice of the user in terms of the category Console.WriteLine("Enter the Category to play - Book/Movie"); Category = Console.ReadLine(); Category = Category.ToUpper();

if (Category != "BOOK" && Category != "MOVIE") { Console.WriteLine("Invalid Category ....\n"); return 0; } else { ExtractName(); return 1; } } public void ExtractName() { //Creating the object of the Random class Random RandGen = new Random(); if (Category == "BOOK") { //Randomly selecting book name from the array int Rnd = RandGen.Next(0, bookCount - 1); //Calling the play method randomString = bookData[Rnd]; } else { //Randomly selecting Movue name from the array int Rnd = RandGen.Next(0, movieCount - 1); //Calling the play method randomString = movieDate[Rnd]; } } /* This method will allow the user to give the characters and * displaying his status as to WON or lost */ public void StartGame() { //Calculating the length of movie/book name dataLength = randomString.Length;

Page 155: C#

//declaring variables char locateChar; int correctCnt = 0, inCorrectCnt = 0; int i, k; //Declaring string to store user input char[] s = new char[randomString.Length]; //Loop to accept the characters and its positions //Loop allows user to attempt 2 times more than the total characters InitializeUserString(); ShowUserInputString(); if (Category == "BOOK") { Console.WriteLine("The total number of characters in the book : {0}", randomString.Length); Console.WriteLine("The total number of characters you can enter to guess the name of the book: {0}", randomString.Length + 2); } else { Console.WriteLine("The total number of characters in the movie : {0}", randomString.Length); Console.WriteLine("The total number of characters you can enter to guess the name of the movie: {0}", randomString.Length + 2); } for (i = 1, k = 0; i <= dataLength + 2 || k == dataLength; i++) { if (correctCnt == dataLength || inCorrectCnt == dataLength) break; Console.WriteLine("Enter the char"); locateChar = Convert.ToChar(Console.ReadLine().ToLower()); int foundPos = 0; int foundChar = 0; //To extract each character of a string foreach (char c in randomString) { if (c == locateChar) { UpdateString(foundPos, locateChar.ToString()); k++; foundChar = 1; } foundPos++; } if (foundChar == 0) { Console.WriteLine("Wrong Attempt...Better Luck Next time \n \n"); inCorrectCnt++; } else {

Page 156: C#

correctCnt++; } ShowUserInputString(); Console.WriteLine("Total Correct Attempts : {0}\t", correctCnt); Console.WriteLine("Total Incorrect Attempts: {0}\t", inCorrectCnt); if (k == dataLength) break; } if (randomString == userString) { Console.WriteLine("You have Won \n"); } else { Console.WriteLine("The correct name is {0}", randomString); Console.WriteLine("You have Lost \n"); }

} public void UpdateString(int fPos, string updateStr) { string beforeString, afterString; if (fPos != 0 && fPos != dataLength - 1) { if (fPos == 1) beforeString = userString.Substring(0, 1); else beforeString = userString.Substring(0, fPos); afterString = userString.Substring(fPos + 1, dataLength - (fPos + 1)); userString = beforeString + updateStr + afterString; } if (fPos == 0) { afterString = userString.Substring(fPos + 1, dataLength - (fPos + 1)); userString = updateStr + afterString; } if (fPos == dataLength - 1) { beforeString = userString.Substring(0, fPos); userString = beforeString + updateStr; } } public void InitializeUserString() { userString = " "; for (int i = 0; i < dataLength; i++) { userString = userString.Insert(i, "*"); } } public void ShowUserInputString() {

Page 157: C#

Console.Clear(); Console.WriteLine("Input value: {0}", userString); } } class Game { static void Main(string[] args) { Console.Clear(); Console.WriteLine("You have to complete the game within 60 seconds"); Hangman obj = new Hangman(); int returnVal = obj.AcceptCategory(); if (returnVal == 1) { //obj.StartGame(); Thread t = new Thread(new ThreadStart(obj.StartGame()); Thread.Sleep(60000); //Making the main thread sleep for 90 seconds try { t.Abort(); Console.WriteLine("Time Over"); } //Killing the new thread catch (ThreadAbortException e) { Console.WriteLine(e.Message); } } Console.ReadLine(); } }}

Task 3: Build and execute the applicationTo build and execute the application perform the following steps:

1. Build the solution by pressing Ctlr + Shift +b2. Select Debug Start Debugging or press F5 to execute the application3. Verify the output of the application

Implementing Multithreading

Multithreading helps to perform various operations simultaneously and saves time of a user. a multithreaded program has a main thread and other user-defined threads to perform multiple tasks simultaneously.

The microprocessor allocates memory to the processes that you execute. Each process occupies its own address space or memory. However, all the threads in a process occupy the same address space. Multithreading allows you to achieve multitasking in a program. Multitasking is the ability to execute more than one task at the same time. Multitasking can be divided into the following categories:

Process-based Multitasking: This multitasking feature enables you switch from one program to another so fast that it appears as if the programs are executing at the same

Page 158: C#

time. For example, process-based multitasking enables you to run the C# compiler and use the text editor at the same time.

Thread-based Multitasking: A single program can contain 2 or more threads and therefore, perform two or more tasks simultaneously. For example, a text editor can perform writing to a file and print a document simultaneously with separate threads performing the writing and printing actions. In the text-editor, you can format text in a document and print the document at the same time. There are fewer overloads when the processor switches from one thread to another. Therefore, threads are called lightweight processes. On the other hand, when the processor switches from one process to another process the overload increases.

Advantages and Limitation of Multithreading

This section list some of the advantages and limitations of multithreading.

The advantages of multithreading are: Improved Performance: Provides improvement in the performance of the processor by

simultaneous execution of computation and the I/O operations. Minimized system resource usage: Minimize the use of system resources by using

threads, which share the same address space and belong to the same process. Simultaneously access to multiple applications: Provides access to multiple

applications at the same time because of quick context switching among threads. Program structure simplification: Simplifies the structure of complex applications, such

as multimedia applications. Each activity can be written in separate methods that makes complex program easy to design and code.

Limitations of multithreading

The limitations of multithreading are: Race condition: When two or more threads simultaneously access a variable, at least

one thread tries to write a value in the variable. This is called the race condition, which is caused by the lack of synchronization between two threads. For example, in a word processor program, there are 2 threads, one to read from a file and the other to write to a file. The thread to read a file waits for the thread to write before performing its operation. The race condition arises when the thread to read a file, reads the file, before the thread to write to a file performs its operation.

Deadlock condition: This condition arises in a computer system when two threads wait for each other to complete their operations before performing their individual action. As a result, the two threads become locked and the program fails. For example, there are two threads, ThreadA and ThreadB. ThreadA is waiting for a lock to be released by ThreadB, and ThreadB is waiting for the lock to be released by ThreadA to complete its transaction. This state is a deadlock.

Lock starvation: This limitation arises when the execution of a thread is postponed because of its low priority. The .NET runtime environment exexutes threads based on their priority because the processor can execute only one thread at a time. The thread with the higher priority is executed before the thread with a lower priority.

Creating Multiple Threads

You can create multiple threads in a program by extending the Thread class. You can use the following code to create two child threads other than the main thread:using System;using System.IO;using System.Threading;class ThreadSchedule {

Page 159: C#

public static void ChildThread1() { Console.WriteLine("Child Thread 1 started"); Console.WriteLine("Child Thread - counting from 1 to 10"); for (int T = 1; T < 11; T++) { for (int Cnt = 0; Cnt < 100; Cnt++) { Console.WriteLine("."); //code to imitatte work being done } Console.WriteLine("{0}", T); } Console.WriteLine("Child Thread 1 is finished"); } public static void ChildThread2() { Console.WriteLine("Child Thread 2 started"); Console.WriteLine("Child Thread - counting slowly from 11 to 20"); for (int T = 11; T < 20; T++) { for (int Cnt = 0; Cnt < 100; Cnt++) { Console.WriteLine("."); //code to imitatte work being done } Console.WriteLine("{0}", T); } Console.WriteLine("Child Thread 2 is finished"); } public static void Main() { ThreadStart Child1 = new ThreadStart(ChildThread1); ThreadStart Child2 = new ThreadStart(ChildThread2);

Console.WriteLine("Main - Creating Child Threads");

Thread Thread1 = new Thread(Child1); Thread Thread2 = new Thread(Child2);

Thread1.Start(); Thread2.Start(); } }

Identifying the Thread Priority

One of the attributes that controls the behavior of a thread is it priority. The .NET Run-time enviromement exexutes threads based on their priority. Only one thread is executed by the CPU at a time. Therefore, the threads, which are at the runnable state for execution, queue up for their turn to get executed by the processor. The threads are fixed priority scheduled. Each thread with its priority has its position in the thread queue of the processor.

Defining Thread Priority

Page 160: C#

Thread priority is the property that specifies the priority of one thread with respect to the priority of another thread. Execution of multiple threads is scheduled on a single processor in a specified order. Thread priority can be defined as:

Above normal Below normal Highest Lowest Normal

A thread with higher priority runs before threads, which have lower priority. If C# encounters another thread with higher priority, the current thread is pushed back; and the thread with the higher priority is executed.

A .NET runtime system selects the runnable thread with the highest priority of execution when a number of threads get ready to execute. The next thread of lower priority starts executing if the higher priority thread stops or becomes not runnable. A thread is pushed back in the queue by another thread if it is waiting from an I/O operation. A thread can also be pushed back in the queue when the time for which the sleep() method was called on another higher priority thread is over.

Setting the Thread priority

You can set the thread priority after it is created using priority property of the Thread class. The following syntax shows how to set the priority property:

Thread1.Priority = ThreadPriority.Highest;

In the preceding syntax, the ThreadPriority.Highest property specifies the new priority setting for a thread. Threads are scheduled for execution based on their priority. Even though threads are executing within run time, all threads are assigned processor time slices by the operating system. The details of the scheduling algorithm used to determine the order in which threads are executed varies with each operating system.

In multiple threads with the same priority are available, the scheduler cycles through the threads in that priority, giving each thread a fixed time slice in which to execute. As long as a thread with a higher priority is available to run, lower priority threads do not get to execute. When there are no more runnable threads at a given priority, the scheduler moves to the next lower priority and schedules the threads at that priority for execution.

You can use the following code, to set the priority of the child threads:

using System;using System.IO;using System.Threading; class ThreadSchedule { public static void ChildThread1() { Console.WriteLine("Child Thread 1 started"); Console.WriteLine("Child Thread - counting from 1 to 10"); for (int T = 1; T < 11; T++) { for (int Cnt = 0; Cnt < 100; Cnt++) { Console.WriteLine(".");

Page 161: C#

//code to imitatte work being done } Console.WriteLine("{0}", T); } Console.WriteLine("Child Thread 1 is finished"); } public static void ChildThread2() { Console.WriteLine("Child Thread 2 started"); Console.WriteLine("Child Thread - counting slowly from 11 to 20"); for (int T = 11; T < 20; T++) { for (int Cnt = 0; Cnt < 100; Cnt++) { Console.WriteLine("."); //code to imitatte work being done } Console.WriteLine("{0}", T); } Console.WriteLine("Child Thread 2 is finished"); } public static void Main() { ThreadStart Child1 = new ThreadStart(ChildThread1); ThreadStart Child2 = new ThreadStart(ChildThread2);

Console.WriteLine("Main - Creating Child Threads");

Thread Thread1 = new Thread(Child1); Thread Thread2 = new Thread(Child2);

Thread1.Priority = ThreadPriority.Highest; Thread2.Priority = ThreadPriority.Lowest;

Thread1.Start(); Thread2.Start(); } }

When a processor is informed about the priority of a thread, the operating system eventually uses the information as a part of its scheduling algorithm. The processor then relays that information. In .NET, this algorithm is based on the priority level used with the Thread1.Priority property, as well as the process’ priority class in the preceding code.

Using Synchronization in Threads

In a multithreaded application, when threads need to share data with each other, the application should ensure that one thread does not change the data used by the other thread. For example, if you have two threads, one that reads your salary from a file and another thread that tries to update the salary, data corruption might occur. C# enables you to coordinate the actions of multiple threads by using synchronized methods or synchronized statements.

Synchronizing Threads

Page 162: C#

Synchronization of threads ensures that if two or more threads need to access a shared resource then that resource is used by only one thread at a time. You can synchronize your code using the synchronized keyword. You can invoke only one synchronized method for an object at any given time.

Synchronization is based on the concept of monitoring. A monitor is an object that is used as a lock to the data members and methods of a class. All objects and classes are associated with the monitor and only one thread can own the monitor at a given time. To enter an object’s monitor, you need to call a method that has been modified with the synchronized keyword.

The monitor controls the way in which synchronized methods access an object or a class. When a thread acquires a lock, it is said to have entered the monitor. The monitor ensures that only one thread has access to the resources at any given time.

When a thread is within a synchronized method, all the other threads that try to call it on the same instance have to wait. During the execution of a synchronized method, the object is locked so that no other synchronized method can be invoked. The monitor is automatically released when the method completes its execution. The monitor can also be released when the synchronized method executes the Wait() method.

When a thread calls the Wait() method, it temporarily releases the locks that it holds. In addition, the thread stops running and is added to the list of waiting threads for that object.

The following figure shows how to synchronization is maintained among threads.g

Locking Code using the Monitor Locks

The System.Monitor enables you to sterlize the access to blocks of code by means of locks and signals. For example, you have a method that writes content to a file and the method cannot be executed by two or more threads at the same time. If the work being performed by this method is

created

running

Entering monitor

Running monitor

Waiting condition

Dead

Signaling Condition

Leaving monitor

Wait ()

Signaled by other thread

Leave monitor

Leave monitor

terminateStart( )

Page 163: C#

especially time-consuming and you have multiple threads, any of which might call this method, you could have a serious problem on your hands. This is where the Monitor class proves useful.

Consider an example on synchronization. You have two threads, both of which will call the WriteData() method. To incorporate the Monitor class in this example, you can use two of its static methods. The first method is called Enter. When executed, this method attempts to obtain a monitor lock on the object. If another thread already has the lock, the method will block until that lock has been released. The Monitor.Exit() method is then called to release the lock.

The following example forces the serialization of access to the WriteData () method:

namespace ThreadExample{ class FileAccess { public void WriteData(string Data) { Monitor.Enter(this);

Console.WriteLine("FileAccess.WriteData - Started"); Console.WriteLine("FileAccess.WriteData - Working"); for (int Cnt = 0; Cnt < 100; Cnt++) { Console.WriteLine(Data); } Console.WriteLine("FileAccess.WriteData - Ended"); Monitor.Exit(this); } } class ThreadMonitorClass { public static FileAccess Fd = new FileAccess(); public static void ChildThread1() { Console.WriteLine("Child Thread 1 started"); Console.WriteLine("Child Thread 1 Calling FileAccess.WriteData"); Fd.WriteData("T1"); Console.WriteLine("Child Thread 1 - Returned from output"); } public static void ChildThread2() { Console.WriteLine("Child Thread 1 started"); Console.WriteLine("Child Thread 1 Calling FileAccess.WriteData"); Fd.WriteData("T1"); Console.WriteLine("Child Thread 1 - Returned from output"); } public static void Main() { ThreadStart Child1 = new ThreadStart(ChildThread1); ThreadStart Child2 = new ThreadStart(ChildThread2);

Console.WriteLine("Main - Creating Child Threads");

Thread Thread1 = new Thread(Child1);

Page 164: C#

Thread Thread2 = new Thread(Child2);

Thread1.Start(); Thread2.Start(); Console.ReadLine(); } }

}

Using Monitor Locks with the C# Lock Statement

The other way to lock code is by using the C# lock statement. Although the C# lock statement does not support the full array of features found in the Monitor class, it enables you to obtain and release a monitor lock. To use the lock statement, simply specify the lock statement with the code being serialized in braces. The braces indicate the starting and stopping point of code being protected. Therefore, there is no need for an unlock statement.

The following code will produce a synchronized output that is similar to the output of the preceding code:

using System;using System.IO;using System.Threading;namespace ThreadExample{ class FileAccess { public void WriteData(string Data) { lock (this) { Console.WriteLine("FileAccess.WriteData - Started"); Console.WriteLine("FileAccess.WriteData - Working"); for (int Cnt = 0; Cnt < 100; Cnt++) { Console.WriteLine(Data); } Console.WriteLine("FileAccess.WriteData - Ended"); } } } class ThreadMonitorClass { public static FileAccess Fd = new FileAccess(); public static void ChildThread1() { Console.WriteLine("Child Thread 1 started"); Console.WriteLine("Child Thread 1 Calling FileAccess.WriteData"); Fd.WriteData("T1"); Console.WriteLine("Child Thread 1 - Returned from output"); } public static void ChildThread2() {

Page 165: C#

Console.WriteLine("Child Thread 2 started"); Console.WriteLine("Child Thread 2 Calling FileAccess.WriteData"); Fd.WriteData("T1"); Console.WriteLine("Child Thread 2 - Returned from output"); } public static void Main() { ThreadStart Child1 = new ThreadStart(ChildThread1); ThreadStart Child2 = new ThreadStart(ChildThread2);

Console.WriteLine("Main - Creating Child Threads");

Thread Thread1 = new Thread(Child1); Thread Thread2 = new Thread(Child2);

Thread1.Start(); Thread2.Start(); Console.ReadLine(); } }

}

Identifying Communication Between Processes

A process is a running instance of a program. The communication between the processes at run time wihtin the same computer or over a network is called the interprocess communication. To allow the interprocess communication, special techniques and mechanisms are used.

Consider an example. Imagine you are typing a document. You use your fingers to type? Your brain works while you are typing the document. Your brain directs one of your fingers to hit a key while the other finger hits another key. Your brain synchronizes typing with both your hands. It directs you to type the letters of a word that come to your mind. The working of your brain is an example of interprocess communication within human body.

Based on this example, you can conclude that a medium is required for communication between various processes. Similarly, computer programs need some mechanism for communication. Processes can use the available memory of the system to communicate with each other, but memory is completely managed by the operating system.

A process will be allotted some part of the available memory for execution by the operating system. Each process will execute in its own unique user space. The operating system will not allow the memory alloted for one process to overlap with the memory allotted for another process. To allow communication between various processes with a unique address space, the operating system’s kernel acts as the communication channel.

Application Domain

Whenever you start an application in OS such as Windows XP, the system starts a Win32 process and executes your application. These processes use resource such as memory, objects,

Page 166: C#

and kernel. Each Win32 process contains at the least one thread. If you were to run other tasks or open up other applications through your application, those tasks will belong to the Win32 process running on a collection of multiple threads.

So when an application is run, a new application domain is created. Several instantiations of an application can exist on the same machine at a given time, and each has its own application domain. An application domain enables application isolation by acting as a container for application state.

In .NET, threads execute in an application domain. A thread in one process cannot invoke a method in a thread that belongs to another process. In .NET, however, threads can cross the application domain boundaries, and a method in one thread can call a method in another application domain. The application domain is a logical process inside a physical process.

The execution of a process and running your code within it is usually the domain and choice of the operating system. There are many complex situations and issues that the operating system has to handle while maintaining an active process. The following figure shows various application domains interacting with each other.

The main purpose of the application domain is to isolate your applications from the other applications. Application domains run on a single process.

Therefore, you run an application within an application domain and you run multiple application domains within a single process. With the .NET CLR’s ability to run a managed code, you can further prevent memory leaks and crashes. Objects in the same application domain communication directly, while objects that exists in different application domains interact with each other by transporting copies of the objects to each other.

You use the System.AppDomain class to manage application domains. The AppDomain class implements a set of events that enable applications to respond when an assembly is loaded, when an application domain will be unloaded, or when an unhandled exception is thrown.

AppDomain A

Object 1

AppDomain B

Object 2

Process 1 Process 2

Operation System Environment

Page 167: C#

Practice Questions

1. Which of the following is true about the ‘not runnable’ state of a thread?a) A sleeping thread enters that ‘not-runnable’ state when the specified time has

elapsedb) A thread is in a ‘not-runnable’ state if it is deadc) When the start() method is invoked, the thread enters the ‘not-runnable’ state.d) When the thread is blocked by another thread, it enters the ‘not-runnable’ state.

2. You need to create a spreadsheet application with automatic recalculation facility. Which of the following statements is/are true with respect to the required application?

A. The application should be multithreadedB. A thread object has to be created for performing automatic

recalculationC. The thread taking care of automatic recalculation should have the

highest priority.

b) A onlyc) A, B & Cd) B & Ce) A & B

3. Which class is used to construct and access individual threads in a multithreaded application?

a) System.Threadb) System.Threadingc) System. Thread .Threadingd) System.Threading.Thread

4. You are creating an application, using the concept of multithreading, in which you can pla audio files and watch animated images at the same time. Which of the following methods should be invoked for a thread to enter the runnable state?

a) Start()b) Sleep()c) Run()d) Resume()

5. You are developing a multithreaded application. Which of the following will you use to make a thread, animThread, enter the non-runnable state?

a) Thread animThread = new Thread(this);b) animThread.Sleep(2000);c) animThread.Resume();d) animThread.Start();

Summary

In this chapter, you learned that: A thread is defined as the path of execution of a program. It is sequence of instructions

that is executed to define a unique flow of control. A program that creates two or more threads is called a multithreaded program. The types of multitasking are:

o Process-based multitaskingo Thread-based multitasking

Page 168: C#

The advantage of multithreading are:o Improved performanceo Minimized system resources usageo Simultaneous access to multiple application

The various disadvantages of multithreading are:o Race conditiono Deadlock conditiono Lock starvation

The System.Threading class is used to construct and access individual threads in a multithreaded application.

The various states in the life cycle of a thread are:o Unstarted stateo Runnable stateo Not Runnable stateo Dead State

Thread priority is the property that specifies the priority of one thread with respect to the priority of another thread.

Synchronization of threads ensures that if two or more threads need to access a shared resource then that resource is used by only one thread at a time.

The System.Monitor class enables you to serialize the access to blocks of code by means of locks and signals

The communication between processes at runtime within the same computer or over a network is called inter-process communication.

The application domain is a logical process inside a physical process. The main purpose of the application domain is to isolate your applications from the other applications.

Exercises

Exercise 1

Write an application to simulate the vehicles crossing a toll bridge on a motorway. For the purpose of this exercise, simulate the environment for five vehicles that are approaching the bridge and the toll booth. The vehicles are numbered from one to five. The vehicles should approach the bridge and the toll booth in sequential order. The toll booth can only deal with one vehicle at a time. The simulation is performed by having one thread for each vehicle, and consists of three classes.

Vehicle: Simulate the behavior of a vehicle Tollbooth: Simulate the behavior of a Tollbooth Simulate: Creates the vehicle and controls the simulation

Chapter 12

Delegates and Events

Classes are reference types that allow you to create instances of objects and use them in special ways to meet your application’s requirement. Another reference type in C# is delegate. Delegates allow you to change the reference to a method at runtime. This means that you can decide the execution of a method at runtime, based on the requirements of your application.

The method can be activated at the occurrence of an event, where an event is associated with the delegate to call the method at runtime.

This chapter discusses the creation of delegates. This chapter also discusses how to implement multicast delegates. In addition, it discusses how you can use events with delegates.

Page 169: C#

Objectives

In this chapter, you will learn to: Implement delegates Implement multicast delegates Use events with delegates

Introducing Delegates

Delegates in C# allow you to dynamically change the reference to the methods in a class. Consider an example of a coffee vending machine, which dispenses different flavors of coffee, such as cappuccino and black coffee. On selecting the desired flavor of coffee, the vending machine decides to dispense the ingredients, such as milk powder, coffee powder, hot water, cappuccino coffee powder. All the materials are placed in different containers inside the vending machine. The required material is dispensed when you select a flavor.

Suppose, you select black coffee, the vending machine will call methods to dispense hot water and coffee powder only. The reference to these methods is made dynamically, when you press the required button to dispense black coffee.

A delegate is a reference type variable, which holds the reference to a method. This reference can be changed at runtime, as desired. Although, delegates are a general-purpose mechanism for indirectly calling methods at runtime, their primary use in C# programming is for implementing events and the call-back methods.

To implement delegates in your application you need to declare delegates, instantiate delegates and use delegates.

Declaring Delegates

The methods that can be referenced by a delegate are determined by the delegate declaration. The delegate can refer to the methods, which have the same signature as that of the delegate.

Consider the following example of delegate declaration:

public delegate void MyDelegate(string s);

In the preceding example, the declared delegate type can be used to reference any method. This method should have a single parameter of string type and it does not return any value.

The following syntax is used for delegate declaration:

delegate <return type><delegate-namespace><Parameter list>

Instantiating Delegates

Create the delegate object of the delegate type, which you have already created. Assign the address of the required method to the delegate object. This can be done by calling the constructor of the delegate class and passing the method name. the following example shows how to assign the address of a method to a delegate variable:

public void DelegateFunction(string PassValue) { //Method Implementation here

Page 170: C#

} //Delegate Declaration public delegate void MyDelegate(string ArgValue); public void UseMethod() { //Delegate Instantiation MyDelegate DelegateObject = new MyDelegate(DelegateFunction); }

In the preceding example, the signature and the return type of DelegateFunction matches with the delegate declaration of the MyDelegate delegate, the MyDelegate delegate can hold the address of DelegateFunction is assigned to the DelegateObject by passing, the name of the function to the delegate constructor.

Using Delegate

You can call the delegate by giving the name of the delegate and by passing parameters, if required. Using delegates is similar to calling methods.

Consider a situation where you need to print information to a file and a screen. There is some common information that needs to go to the file and to the screen. There is also some specific information for both. The methods to print the information to the file and screen are different. You can call these methods at runtime by passing the common information.

The following example shows how to use a delegate:

//This code is to print data to the output device, which is either a file or a screenusing System;using System.IO;//Program to write the data to the console and filenamespace Chapter12Ex1{ public class PrintToDevice { //Creating the variables of Stream classes static FileStream Fstream; static StreamWriter SWriter; //Defining a delegate public delegate void PrintData(string s);

//Method to print a string to the console

public static void WriteConsole(string str) { Console.WriteLine("{0} Console",str); } //Method to print a string to a file public static void WriteFile(string s) { //Initializing stream objects Fstream = new FileStream("C:\\StoreData.txt", FileMode.Append, FileAccess.Write); SWriter = new StreamWriter(Fstream);

Page 171: C#

s = s + "File"; //Writing string to the file SWriter.WriteLine(s); //removing the content from the buffer SWriter.Flush(); SWriter.Close(); Fstream.Close(); } //Method to send the string data to respective methods public static void DisplayData(PrintData PMethod) { PMethod("This should go to the ")" } public static void Main() { //Initializing the Delegate Object

PrintData Cn =new PrintData(WriteConsole); PrintData Fl = new PrintData(WriteFile); //Invoking the DisplayData method with the delegate object as the argument //Using the delegate DisplayData(Cn); DisplayData(Fl); Console.ReadLine(); } }}

In the preceding example, the WriteConsole () and WriteFile () methods are used to write the information to the screen and to the file. The delegate variable PrintData is used to refer to the WriteConsole () and WriteFile () methods.

Delegates are of two types and depending upon the requirement of the application the similar type of delegate is selected.

Types of Delegates

There are two types of delegates, Single-cast delegate and Multicast delegate. A Single-cast delegate can call only one method at a time, whereas a Multicast delegate can call multiple methods at the same time.

Single-Cast Delegate

A single-cast delegate derives from the System.Delegate class. It contains reference to one method only at a time. In the preceding example, the delegate used is a single-cast delegate. The WriteConsole () and WriteFile () methods are being referenced by the delegate, PrintData, one after the other, at runtime.

Consider the coffee vending machine example. To provide black coffee a delegate that holds the reference to the methods to dispense hot water and coffee powder is used. The reference to these methods is made dynamically, but one after the other. This means coffee powder and hot water will be dispensed from the machine serially.

Multicast Delegate

Page 172: C#

A multicast delegate derives from the System.Delegate class. It contains an invocation list of multiple methods. In multicasting you create a single delegate that invokes multiple encapsulated methods. You need to ensure the return type of all these delegates is same.

Consider the coffee vending machine example. You are dispensing black coffee, which in turn calls the methods to dispense hot water and coffee powder. If you want the methods to dispense hot water and coffee powder to be called at the same time, you can make use of a multicast delegate.

Multicast delegates hold the reference of more than one method thereof, if you call a multicast delegate it will execute all the methods it wraps in the calling order. The multiple methods called by the delegate in this case should not return any value because several multicast delegates are called consecutively and you cannot wait to get the return value from each of these methods.

Consider the preceding example of printing a message to a file and to a screen in which the WriteConsole () and WriteFile () methods are called by using a single-cast delegate. This example considers a situation where all the methods are called at the same instance. Using the same delegate, multicasting helps to call both the WriteFile () method and the WriteConsole () method in one call.

The following code shows how to use a multicast delegate:

//This code is to print data to the output device, which is either a file or a screenusing System;using System.IO;

//Program to write the data to the console and filenamespace Chapter12Ex1{ public class PrintToDevice { //Creating the variables of Stream classes static FileStream Fstream; static StreamWriter SWriter; //Defining a delegate public delegate void PrintData(string s);

//Method to print a string to the console

public static void WriteConsole(string str) { Console.WriteLine("{0} Console", str); } //Method to print a string to a file public static void WriteFile(string s) { //Initializing stream objects Fstream = new FileStream("C:\\StoreData.txt", FileMode.Append, FileAccess.Write); SWriter = new StreamWriter(Fstream); s = s + "File"; //Writing string to the file SWriter.WriteLine(s); //removing the content from the buffer

Page 173: C#

SWriter.Flush(); SWriter.Close(); Fstream.Close(); } //Method to send the string data to respective methods public static void DisplayData(PrintData PMethod) { PMethod("This should go to the "); } public static void Main() { //Initializing the Delegate Object

PrintData MIDelegate = new PrintData(WriteConsole); MIDelegate += new PrintData(WriteFile); DisplayData(MIDelegate); MIDelegate -= new PrintData(WriteFile); DisplayData(MIDelegate); Console.ReadLine(); } }}

In the preceding example, the multicast delegate, MIDelegate holds reference of both the WriteConsole () and WriteFile () methods.

Just a Minute

State whether the following statement is True or False:

Multicast delegates inherit from the System.Delegate.MulticastDelegate class.

Answer:

False.

Working with Events

An event is an action or occurrence, such as clicks, key presses, mouse movements, or system generated notifications. Applications can respond to events when they occur. An example of a notification is interrupts. Events are messages sent by the object to indicate the occurrence of the event. Events are an effective mean of inter-process communication. They are useful for an object because they provide signal state changes, which may be valuable to a client of the object.

Consider an example of an event and the response to the event. A clock is an object that shows 6 AM time and generates an event in the form of an alarm. You accept the alarm event and act accordingly.

The following figure shows the alarm event and handling of an event.

Page 174: C#

The following figure is the generalized representation that explains events and event handling

In C#, delegates are used with events to implement event handling. The .NET Framework event model uses delegates to bind event notifications with methods known as event handlers. When an event is generated, the delegate calls the associated event handler.

Using delegates with Events

Clock shows time.Time is 6 AM

Alarm plays a sound, notifying everyone that is 6 AM

You hear the alarm

You get up and get ready for your school

An event occurs in an object

Object notifies everyone that the event has occurred

Someone listens for the event

Someone acts upon it

Page 175: C#

The events are declared and raised in a class and associated with the event handlers using delegates within the same class or other classes. Events are part of a class and the same class is used to publish its events. The other classes can, however, accept these events or in other words can subscribe to these events. Events use the publisher and subscriber model.

A publisher is an object that contains the definition of the event and the delegate. The association of the event with the delegate is also specified in the publisher class. The object of the publisher class invokes the event, which is notified to the other objects. A subscriber is an object that wants to accept the event and provide a handler to the event. The delegate of the publisher class invokes the method of the subscriber class. This method in the subscriber class is the event handler. The publisher and subscriber model implementation can be defined by the same class.

The following figure shows the mechanism used by the publisher and subscriber object.

The implementation of an event includes events definition, events subscription and events notification.

Defining an Event

The definition of the event in a publisher class includes the declaration of the delegate as well as the declaration of the event based on the delegate. the following code defines a delegate named TimeToRaise and an event named RingAlarm, which invokes the TimeToRaise delegate when it is raised:

public delegate void TimeToRaise();public event TimeToRaise RingAlarm;

Declare a delegate

Declare an Event based on the delegate

Fire the Event

Subscribed Event

Event Handler

Fires the event handler

Subscriber

Subscribed Event

Event Handler

Fires the event handler

Subscriber

Publisher

Page 176: C#

Subscribing to an Event

The event of the publisher class needs to be associated with its handler. The event handler method is associated with the event using the delegate. when the publisher object raises the event, the subscribing object associates the method, which needs to be called.

Consider the class named Student which contains a method named WakeUp(). The requirement states that the method WakeUp() should be called at 6 A.M. The requirement could be implemented using events. The following code shows how the Student class subscribes to the event named TimeToRaise:

Student PD = new Student();RingAlarm = new TimeToRaise(PD.WakeUp);

Note:

The delegates that subscribe to an event must be declared void.

Notifying Subscribers to an Event

The subscriber object notifies the subscriber object to the publisher object. The event is raised to notify the handler.

In the RingAlarm example, you do not require the WakeUp () method to be executed through the delegate because the event takes care of execution. Write this block of code at a place from where you want to notify the event to the subscribers of the event:

if (RingAlarm != null) { RingAlarm(); }

The preceding code block invokes all the associated delegates. In this example, the WakeUp () method that subscribes to the event is activated. Notice, code checks if the event has at least one subscribing delegate. without this check, code throws an exception if there are no subscribers.

Passing Event Parameters

The methods that subscribe an event might expect some input to be passed. The event class can have these inputs at runtime on which the subscribing method works. You need to define the class that will pass the input to the event.

Derive this class from System.EventArgs. To pass values to a subscribing method, you need to enclose the parameters in a single class. The single class supplies a special method called the accessor method to retrieve the value. This method is used to examine and modify the members of a class. Variables declared private are accessed indirectly through these methods.

In the preceding RingAlarm example, the WakeUp() method needs to get information about time so that it can work. Therefore, you create the class to pass the information about time to the subscriber through the event.

The following code passes the information about time to the subscriber through the event:

public class TimeInfoEventArgs : EventArgs { private int Hour;

Page 177: C#

private int Minute; private int Second; public TimeInfoEventArgs(int Hour, int Minute, int Second) { this.Hour = Hour; this.Minute = Minute; this.Second = Second; } public int GetHour { return Hour; } public int GetMinute { return Minute; } public int GetSecond { return Second; } }

The TimeInfoEventArgs class is the event class that will pass the value of hour, minute and second. The class declares three accessor methods: GetHour , GetMinute and GetSecond.

Activity : Attendence Log

Problem Statement

In an air-conditioner manufacturing company, the working time is from 9 AM and 6PM. The management of the company is flexible and it allows workers to arrive to work late by 1 hour. The entry time of workers is recorded electronically in a log file when they enter the premises of the company. The application used for recording the attendance of each worker needs to log the appropriate information.

Help the company to design an application for logging attendance.

Solution

To design the application, you need to perform the following tasks:1. Identify the technique that you will use in the application. This technique will allow you to

call the respective methods dynamically to log the attendance entry.2. Create a console-based application to implement the attendance log of workers3. Compile and execute the application.

Task 1: Identify the technique that you will use in the application. This technique will allow you to call the respective methods dynamically to log the attendance entry.

To demonstrate the working of the Attendance Log Entry application, various methods are required to be called dynamically. You can use a delegate to call methods dynamically. You need to keep in mind that in the future the company may start new shifts. The attendance entry can be treated as an event. That event delegates attendance logging of workers to methods.

Task 2: Creating a console-based application

Page 178: C#

To create a console based application for the Hangman game, you need to perform the following steps:

1. Select Start All Programs Microsoft Visual Studio 2005 Microsoft Visual Studio 2005. The Start Page – Microsoft Visual Studio window will be displayed

2. Select File New Project. The New Project dialog box will be displayed3. Select the project type as Visual C# from the Project types pane and Console

Application from the Templates pane.4. Type the name of the new project as AttendanceApp in the Name text box.5. Specify the location where the new project is to be created as c:\chapter12\Activity1 in

the Location combo box.6. Click the OK button.7. Open the Solution Explorer window and right-click the Program.cs file.8. Select the Rename option and type the new name as DelegateEvent.cs9. Double-click the DelegateEvent.cs file in the solution explorer window. The code view

of the DelegateEvent.cs file is displayed10. Replace the existing code with the following code:

using System;using System.IO;

namespace AttendanceApp{ //Event Publisher public class DelegateEvent { //Define a delegate named AttendanceLogHandler, which will //encapsulate //any method that takes a string as the parameter and //returns no value public delegate void AttendanceLogHandler(string Message);

//Define an Event based on the above delegate public event AttendanceLogHandler EventLog;

//Instead of having the LogProcess() function take a //delegate //as a parameter, we've declared a EventLog event. public void LogProcess() { string Reason = null; Console.WriteLine("Enter your name"); string UserName = Console.ReadLine(); DateTime t = DateTime.Now; int hr = t.Hour; int m = t.Minute; if (!(hr >=9 && hr <10 || (hr == 10 && m == 0 ))) { Console.WriteLine("Enter the reason for not coming within the valid time:"); Reason = Console.ReadLine(); } OnEventLog("Logging into Info: " + UserName); if (hr >= 9 && hr <10 || (hr == 10 && m == 0)) if (m<10)

Page 179: C#

OnEventLog("Logged in at " +hr.ToString() + ":0" +m.ToString() + "Within Time"); else OnEventLog("Logged in at " +hr.ToString() + ":" +m.ToString() + "Within Time"); else if (m<10) OnEventLog("Logged in at " +hr.ToString() + ":0" +m.ToString() + "Not Within Time because" +Reason); else OnEventLog("Logged in at " +hr.ToString() + ":" +m.ToString() + "Not Within Time because" +Reason); OnEventLog(" "); } // By default, create an OnZZZZ method, to call the Event protected void OnEventLog(string Message) { if (EventLog != null) { EventLog(Message); } } } //The AttendanceLogger class merely encapsulates teh file I/O public class AttendanceLogger { FileStream FileStr; StreamWriter StreamWtr;

//Constructor public AttendanceLogger(string FileName) { FileStr = new FileStream(FileName, FileMode.Append, FileAccess.Write); StreamWtr = new StreamWriter(FileStr); } //Member Function which is used in the Delegate public void Logger(string LogInfo) { StreamWtr.WriteLine(LogInfo); } public void Close() { StreamWtr.Close(); FileStr.Close(); } } //Subscriber of the Event public class RecordAttendance { static void Logger(string LogInfo) { Console.WriteLine(LogInfo); } static void Main(string[] args) {

Page 180: C#

AttendanceLogger FileLog = new AttendanceLogger("C:\\process.log"); DelegateEvent DEvent = new DelegateEvent();

//Subscribe the Functions Logger and FileLog.Logger DEvent.EventLog += new DelegateEvent.AttendanceLogHandler(Logger); DEvent.EventLog += new DelegateEvent.AttendanceLogHandler(FileLog.Logger);

//The Event will now be triggered in teh LogProcess() method DEvent.LogProcess(); Console.ReadLine(); FileLog.Close(); } }}

Task 3: Build and execute the applicationTo build and execute the application perform the following steps:

1. Build the solution by pressing Ctlr + Shift +b2. Select Debug Start Debugging or press F5 to execute the application3. Verify the output of the application

Practice Questions

1. Identify the correct statement about delegatea. Before you declare an event inside a class, you can optionally declare a delegate

by using the delegate keywordb. The delegate type consists of the set of arguments that it receives from the

method that handles the eventc. Multiple events cannot share the same delegated. By using a single-cast delegate, you can invoke only one method corresponding

to different events

2. Which of the following code is correct to assign more than one method address to a delegate?

a. DelegateVariable = new MyDelegate(Function1) DelegateVariable += new MyDelegate(Function2)

b. DelegateVariable = new MyDelegate(Function1); DelegateVariable += MyDelegate(Function2);

c. DelegateVariable = new MyDelegate(Function1); DelegateVariable += new MyDelegate(Function2+Function2);

d. DelegateVariable = new MyDelegate(Function1); DelegateVariable += new MyDelegate(Function2);

3. State whether the given statement is True or FalseA publisher is an object that contains the definition of the event and the delegate

4. Match the following delegate concepts with there implementation

Delegate Implementation Syntax

Page 181: C#

Declaring delegates TestDelegate var = new TestDelegate(Func);Instantiating Delegates Public delegate void TestDelegate(string arg);Using delegates TestDelegate(“Test”);

5. State whether the given statement is True or FalseDelegates used with the events should be declared void.

Summary

In this chapter, you learned that: Delegates allow you to write code that can dynamically change the methods that it calls. There are two types of delegates, Single-cast delegate and Multicast delegate. A single-cast cast delegate can call only one function. Multicast delegate holds the reference of more than one method. Single-cast delegate derives from the System.Delegate class and multicast delegate

derives from the System.MulticastDelegate. Events are the messages sent by an object to indicate the occurrence of an event. Events use the publisher and subscriber model. A publisher is an object that maintains its internal state. A subscriber is an object that registers an interest in an event.

Exercises

Exercise 1

Write an application that creates a class named Registration. The application would be used by the counselors of an IT education center, while registering students. The registration data entry is done differently for career registration and for Modular registration. You application should have separate class for the two categories of students. You need to record the student’s score of the aptitude test for Career registration. You need to record the student’s prior experience or knowledge for Modular registration.

Hint: Use delegate in the registration class while registering a student to call the appropriate methods.

Chapter 13

Attributes and Reflection

Attributes are a simple technique for adding metadata information and behavior to code within applications. You use the reflection technique to pick the attribute related information at runtime.

This chapter introduces attributes and reflection and the functions they perform in C# applications. This chapter discusses attribute syntax, and how to use some of the predefined attributes. This chapter also discusses how to create customized user-defined attributes. In addition, this chapter discusses reflection and how to use it to extract attribute related information.

Objectives

In this chapter, you will learn to: Describe attributes Retrieve metadata using reflection

Page 182: C#

Introducing Attributes

An object is described by the values of its attributes. For example, a car can be described by its make, model, or color. Similarly, a C# program has certain attributes which depict and influence its behavior, for example, compiler instructions.

An attribute is a declarative tag that is used to convey information to runtime about the behavior of programmatic elements such as classes, enumerators, and assemblies. A declarative tag is depicted by square ([]) brackets placed above the definition of an element such as a class or a method.

Attributes are used for adding metadata, such as compiler instructions and other information such as comments, description, methods, and classes to a program.

Applying attributes

Attributes are applied to different elements of the code. These elements include assemblies, modules, classes, structs, enums, constructors, methods, properties, fields, events, interfaces, parameters, return values, and delegates. Information about attributes is stored with the metadata of the elements they are associated with:

The following syntax enables you to specify an attribute:

[attribute(positional_parameters,name_parameter=value, . ..)] element

In the preceding syntax, an attribute name and its values are specified within square brackets([ ]) before the element to which the attribute is applied. Attributes might required one or more parameters, positional or named. Positional parameters are used to specify essential information of an attribute, whereas named parameters are used to convey optional information of an attribute.

The .NET Framework supports two categories of attributes to be used in C# program: predefined and custom. Predefined attributes are supplied as part of the Common Language Runtime (CLR) and they are integrated into .NET Custom attributes are attributes that you create according to your requirement.

Using Predefined Attributes

Some commonly used predefined attributes provided with .NET Framework are: Conditional: Causes conditional compilation of method calls, depending on the specified

value such as Debug or Trace. For example, it displays the values of variables, when debugging a code. However, this attribute only determines the action that will occur when a method is called. If conditional compilation of a method is required, the #if and #endif directives are used in the code. The methods to which you can apply a conditional attribute are subject to a number of restrictions. In particular, they must have a return type of void and must not be marked as an override, and the implementation of the method should be from an inherited surface.For example:

[ Conditional(“DEBUG”])The preceding statement ensures that the target element, whether a class or a method ensures use of that element in debugging mode only. The other value of this attribute can be:

[ Conditional(“TRACE”]) WebMethod: Identifies the exposed method in a web service. A web service is a web

application that allows you to expose business functionality to other application that allows you to expose business functionality to other applications. Furthermore, the

Page 183: C#

various properties of this attribute enable you to configure the behavior of the exposed method.The following code is an example of using WebMethod attribute:

[WebMethod (Description=”Converts temperature from Fahrenheit to Celsius.”)]public double TempConvert(double myTemp)

{ return ((myTemp - 32) * 5) / 9;

}The preceding code provides an exposed method of a Web Service which converts temperature from Fahrenheit to Celsius. The WebMethod attribute definition above TempConvert() method tells the compiler that it is an exposed method and the Description property of the WebMethod attribute provides information about working of the TempConvert () method

DllImport: Calls an unmanaged code in programs developed outside the .NET environment. An example of such a program is the standard C program compiled into DLL files. By using the DllImport attribute, the unmanaged code residing in DLLs can be called from the managed C# environment.The following code is an example of using DllImport attribute:

using System;using System.Runtime.InteropServices;using System.IO;

namespace AttendanceApp{

class GenerateBeeps { [DllImport(_kernel32.dll.)] [DllImport public static extern bool Beep(int f, int d); static void Main() { Beep(1000,111); } }}

The preceding code uses the Beep() method defined in Kernel32.dll and parameter f and d signify the frequency and duration of beep to generate.

Obsolete: Enables you to inform the compiler to discard a piece of target element such as a method of a class. For example, when a new method is being used in a class but you still want to retain the old method in that class, as a developer, you can mark the old method as obsolete. You mark the old method as obsolete by displaying a message stating that instead of the old method, the new method should be used.

The following code is an example of using Obsolete attribute:using System;public class MyClass { [Obsolete("Don't use the A() method, instead use B() method", true)] static void A() { } static void B() { } public static void Main()

Page 184: C#

{ A(); } }In the preceding code, the first parameter is string, which contains the message. The second parameter tells the compiler to treat the use of the element as an error. The default value is false, which means compiler generates a warning for this.

Creating Custom Attributes

The .NET Framework allows creation of custom attributes, which can be used to store information and can be retrieved at run time. This information can be related to any target element depending upon the design and the need of an application.

Consider this scenario. A software development company wants to keep track of all the bug fixes as a part of its development process. Although, the company maintains a bug database generated during and after the developmental process, the program manager wants to attach proper bug fixing reports in code itself. To address this requirement, developers might add comment statements to code. This following code statement displaying a comment is a bug fix example:

//Bug # 122 fixed by Sara Levo on 8/12/2006

Although, the preceding comment statement gives some information in the source code, but it gives no direct association to Bug # 122, information of which might be stored in the bug database. In such a situation, the custom attribute can help replace the preceding code statement with the following code statement:

[BugFixingAttribute(122,"Sara Levo","8/12/2006") Remarks = "Data Type Mismatch at Line 44"]

A simple program can be written to read through the metadata to find the bug fixing notations and to help update the bug database. Metadata is data about data. In other words, it is information that is used to describe other data.

To create custom attributes, you need to: Define a custom attribute Name the custom attribute Construct the custom attribute Apply the custom attribute to target element

Defining A custom attribute

A new custom attribute is derived from the System.Attribute system class, as shown in the following code:

public class BugFixingAttribute : System.Attribute

You need to then apply the attribute target using a predefined attribute to the new custom attribute class, AttributeUsage, as shown in the following code statement:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor |AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple=true)]

Page 185: C#

The AttributeUsage attribute allows two arguments. One argument is a set of flags that indicates the target element. To continue with the bug fixing example, the AttributeUsage attribute will be the class and its constructor, fields, methods, and properties.

The other argument is a flag that indicates whether a given element might be applied with more than one such attribute. In the preceding code, the AllowMultiple property is set to true, indicating that more than one BugFixingAttribute can be applied to class and its members.

Besides the AllowMultiple property there are other properties that can be used with the attributes. These properties are:

Inherited: A Boolean value “true” for this property indicates that if an attribute is applied to base class and all its derived classes. A value of “false” stops the attribute when it is applied to a subclass.

ValidOn: This property helps define the target elements on which the custom attribute can be applied. The element to which you attach an attribute is called an attribute target. The AttributeTargets enumerator is used for setting all the possible attribute targets.

The following table lists the various member names of the AttributeTargets enumerator.

Member Name Attribute TargetsAll, Elements including assembly, class, class member, delegate, enum,

event, field, interface, method, module, parameter, property, or structAssembly Assembly onlyClass Instances of a classClassMembers Classes, structs, enums, constructors, methods, properties, fields,

events, delegates, and interfacesConstructor Class constructorsDelegate Delegate methodsEnum Defined enumerationEvent Defined eventsField FieldsInterface InterfacesMethod Defining methodsModule A single moduleParameter Parameters of a methodProperty Properties (both get and set, if implemented)Struct structs

Naming the Custom Attribute

Let us continue with the bug fixing example in which the new custom attribute is named as BugFixingAttribute. The normal convention is to append the word Attribute to the attribute name. The compiler supports appending by allowing you to call the attribute with the shorter version of the name.

Therefore, the attribute can be written as shown in the following code statement:

[BugFixingAttribute(122,"Sara Levo","8/12/2006") Remarks = "Data Type Mismatch at Line 44"]

The compiler first looks for the definition of an attribute named BugFixing. When it does not find the definition it looks for the definition with the name BugFixingAttribute.

Page 186: C#

Constrcuting the Custom Attribute

Every attribute must contain at least one constructor. In the following bug fixing example, the bug number, developer’s name, and fixed date are positional parameters and remarks is a named parameter. Positional parameters are passed through the constructor in the order declared in the constructor, as shown in the following code snnipet:

public BugFixingAttribute(int BugNo, string Developer, string DateFixed) { this.BugNo = BugNo; this.Developer = Developer; this.DateFixed = DateFixed; }

Named parameters are implemened as properties, as shown in the following code snnipet:

public string Remarks { get { return Remarks; } set { Remarks = value; } }

It is common to create read-only properties for the positional parameters:

public int BugNo { get { return BugNo; } }

Applying the Custom Attribute:

The attribute can be applied by placing it immediately before its target. To test the BugFixingAttribute attribute for the preceding example, you can create a program for a simple class named Calculator and give it four functions. You need to assign the BugFixingAttribute to the target element class to record its code-maintenance history, as shown in the following code snnipet:

[BugFixingAttribute(125,"Sara Levo","8/15/2006") Remarks = "Return Object not specified"][BugFixingAttribute(159,"Sara Levo","8/17/2006") Remarks = "Data Type Mismatch"]public class Calculator

The BugFixingAttribute attribute will be stored with the metadata. The following code shows the complete lisitng of the bug fixing problem:

Page 187: C#

using System;using System.Reflection;using System.Collections.Generic;using System.Text;

namespace Attribute_Example{ //create a custom attribute to be assigned to class and its members [AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] public class BugFixingAttribute : System.Attribute { private int bugNo; private string developer; private string dateFixed; private string remarks; //attribute constructor for positional parameters

public BugFixingAttribute(int BugNo, string Developer, string DateFixed) { this.bugNo = BugNo; this.developer = Developer; this.dateFixed = DateFixed; } public int BugNo { get { return bugNo; } } public string Developer { get { return developer; } } public string DateFixed { get { return dateFixed; } } public string Remarks { get { return Remarks; } set { Remarks = value;

Page 188: C#

} } } [BugFixingAttribute(125,"Sara Levo","8/15/2006", Remarks = "Return Object not specified")] [BugFixingAttribute(159,"Sara Levo","8/17/2006", Remarks = "Data Type Mismatch")] public class Calculator { public double Add(Double num1, Double num2) { return num1+num2; } public double Subtract(Double num1, Double num2) { return num1-num2; } [BugFixingAttribute(155,"Sara Levo","8/16/2006")] public double Multiply(Double num1, Double num2) { return num1-num2; } [BugFixingAttribute(156,"Sara Levo","8/17/2006")] public double Divide(Double num1, Double num2) { return num1/num2; } } class EntryPoint { static void Main(string[] args) { Calculator myObj = new Calculator(); Console.WriteLine("The sum of specified two nos are {0}", myObj.Add(15,20.5)); Console.ReadLine(); } }}

After executing the preceding code, the program output would be displayed. Open the Attribute_Example.exe using the MSIL Disassembler (IL DSAM.exe). Following are the steps to open Attribute_Example.exe using the MSIL Disassembler:

1. Select Start All Programs Microsoft .NET Framework SDK v2.0 Tools MSIL Disassembler

2. Select File Open. The Open dialog box is displayed.3. Select the Attribute_Example.exe file from the Debug folder of the project.4. Click the OK button. The IL DASM window is displayed,5. Expand the Attribute_Example Attribute_Example.Calculator node.6. Press CTRL+M. The Metadata window is displayed. The Metadata window displays the

complete metadata information containing the created BugFixing custom attributes.

Retrieving Metadata Using Reflection

Page 189: C#

Reflection is used in the process of obtaining type information at runtime. The classes that give access to the metadata of a running program are in the System.Reflection namespace.

The System.Reflection namespace contains classes that allow programmers to obtain information about the application that is running and to dynamically add types, values, and objects to that application.

Reflection is generally used for the following tasks: Viewing metadata: Allows viewing attribute information from the code at runtime Performing type discovery: Allows examining the various types in an assembly and

instantiate those types Late binding to methods and properties: Allows the developer to call properties and

methods on dynamically instantiated objects using type discovery Reflection emit: Allows you to create new types at runtime and then to use those types

to perform tasks

Viewing Metadata

To view metadata using reflection, the MemberInfo object of the System.Reflection needs to be instantiated. This object helps discover the attributes of a member and to provide access to metadata. Taking the bug fixing example further, use reflection to read metadata in the Calculator class. To do this you need to define an object of the Calculator class, as shown in the following code statement:

Type type = typeof(Calculator);

In the preceding code statement the typeof operator on the Calculator type, returns an object of the Type type class. The Type class is the root of the reflection class and it is the primary way to access metadata. It encapsulates a representation of the type of an object. The MemberInfo object of System.Reflection namespace derives from the Type class that encapsulates information about the members of a class.

Then, you need to initiate a call on the GetCustomAttributes() function. This function returns an array of objects, each of type BugFixingAttribute.

The following code shows the modified Main() method of the bug fixing example:

class EntryPoint { static void Main(string[] args) { Calculator myObj = new Calculator(); Console.WriteLine("The sum of specified two nos are {0}", myObj.Add(15, 20.5)); Console.ReadLine();

Type type = typeof(Calculator); //iterating through the attributes of the Calculator class foreach (Object attributes in type.GetCustomAttributes(false)) { BugFixingAttribute myBFAObj = (BugFixingAttribute)attributes; if (null != myBFAObj) {

Page 190: C#

Console.WriteLine("\n Bug #: {0}", myBFAObj.BugNo); Console.WriteLine("\n Developer #: {0}", myBFAObj.Developer); Console.WriteLine("\n Date Fixed #: {0}", myBFAObj.DateFixed); Console.WriteLine("\n Remarts #: {0}", myBFAObj.Remarks); } } //iterating through the attributes of all the methods of a Calculator class foreach (MethodInfo method in type.GetMethods()) { foreach (Attribute attributes in method.GetCustomAttributes(true)) { BugFixingAttribute myBFAObjM = (BugFixingAttribute)attributes; if (null != myBFAObjM) { Console.WriteLine("\n Bug #: {0} for Method {1}", myBFAObjM.BugNo, method.Name); Console.WriteLine("\n Developer #: {0}", myBFAObjM.Developer); Console.WriteLine("\n Date Fixed #: {0}", myBFAObjM.DateFixed); Console.WriteLine("\n Remarts #: {0}", myBFAObjM.Remarks); } } } Console.ReadLine(); } }

The preceding code prints all the bug fixing related inforamtion defined using attributes.

Performing Type Discovery

Reflection also helps to explore and examine the contents of an assembly. It helps find the types associated with a modulel; the methods, fields, properties, and events associated with a type, as well as the signatures of each type of methods; the interfaces supported by the type; and the type’s base class. The type discovery information can also be viewed through the Object Browser window of Visual Studio .NET IDE.

Late Binding to Methods and Properties

Binding a method at runtime is called late-binding. Reflection provides the flexibility of choosing an object you will bind at runtime and calling it programmatically. For example, by using late-binding, you can enable your program to interact with calendar or the other components of a running word processing application such as Microsoft Word.

Reflection Emit

Page 191: C#

Reflection emit allows creation of new types at runtime and further use those types to perform certain tasks. For example, an assembly can be defined to execute dynamically or to save itself to disk. Furthermore, reflection emit enables you to define new modules and new types with methods.

Activity: Creating and Querying Custom Attribute Information

Problem Statement

John is a developer in a software development company. The program manager wants John to ensure proper documentation of the business logic of the Calculator application as a part of development process. Although, the company maintains a separate sheet to describe the use classes and their version number, the program manager wants to attach that sheet to classes.

[Hint: Use the Calculator class given in the preceding section for providing the business logic]

Solution

To create a console-based application for Calculator application, John needs to perform the following tasks:

1. Create a console-based application2. Build and execute an application

Task 1: Creating a Console-based application

To create a console based application, John needs to perform the following steps:

1. Select Start All Programs Microsoft Visual Studio 2005 Microsoft Visual Studio 2005. The Start Page – Microsoft Visual Studio window will be displayed

2. Select File New Project. The New Project dialog box will be displayed3. Select the project type as Visual C# from the Project types pane and Console

Application from the Templates pane.4. Type the name of the new project as AttribNameSpace in the Name text box.5. Specify the location where the new project is to be created as c:\chapter12\Activity1 in

the Location combo box.6. Click the OK button.7. Open the Solution Explorer window and right-click the Program.cs file.8. Select the Rename option and type the new name as DescriptionAttribute.cs9. Double-click the DescriptionAttribute.cs file in the solution explorer window. The

code view of the DescriptionAttribute.cs file is displayed10. Replace the existing code with the following code:

using System;using System.Reflection;using System.Collections.Generic;using System.Text;

namespace AttribNameSpace{ //create DescriptionAttribute custom attribute to be assigned to class members [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] [DescriptionAttribute("This class contains definition of Description Attribute", 1.0)] public class DescriptionAttribute : System.Attribute

Page 192: C#

{ protected string description; protected double version; //attribute constructor for positional parameters public DescriptionAttribute(string Description, Double Version) { this.description = Description; this.version = Version; } public String Description { get { return this.description; } } public double Version { get { return this.version; } set { this.version = value; } } } [DescriptionAttribute("This class contains two methods", 1.0)] public class Calculator { public double Add(Double num1, Double num2) { return num1 + num2; } public double Subtract(Double num1, Double num2) { return num1 - num2; } public double Multiply(Double num1, Double num2) { return num1 - num2; } public double Divide(Double num1, Double num2) { return num1 / num2; } } [DescriptionAttribute("This class contains the main method", 2.0)] public class EntryPoint { public static void Main(string[] args) { Calculator myObj = new Calculator(); Console.WriteLine("The sume of the specified numbers is {0}", myObj.Add(15, 20.5)); Type type = typeof(Calculator);

Page 193: C#

//Specific call should be made to retrieve an attribute properties

//When 2 or more custom attributes are there in an application foreach (Attribute attributes in type.GetCustomAttributes(typeof(DescriptionAttribute),false)) { DescriptionAttribute myDAObj = (DescriptionAttribute)attributes; if (null != myDAObj) { Console.WriteLine("\n Class: Calculator - Description : {0} - Version {1)", myDAObj.Description, myDAObj.Version); } } type = null; type = typeof(EntryPoint); foreach (Object attributes in type.GetCustomAttributes(false)) { DescriptionAttribute myDAObj = (DescriptionAttribute)attributes; Console.WriteLine("\n Class: EntryPoint - Description : {0} - Version {1)", myDAObj.Description, myDAObj.Version); } Console.ReadLine(); } }}

Task 2: Build and execute the applicationTo build and execute the application perform the following steps:

1. Build the solution by pressing Ctlr + Shift +b2. Select Debug Start Debugging or press F5 to execute the application3. Verify the output of the application

Practice Questions

1. State whether the following statement is True or False:Reflection emit allows creation of new types at runtime.

2. Consider the following statementsStatement A : Named parameters are used to specify essential information of an attribute.Statement B: Positional parameters are used to convey optional information in an attribute.

a. Statement A is false, Statement B is trueb. Statement B is true, Statement A is falsec. Both Statements A and B are trued. Both Statements A and B are false

Page 194: C#

3. Which predefined attribute allows you to call an unmanaged code in programs developed outside the .NET environment?

a. Conditionalb. DLLImportc. Obsoleted. WebMethod

4. Attribute property ________ indicates that if an attribute is applied to base class and all its derived classes

5. Which window displays the complete metadata information of an application containing the custom attributes?

Summary

In this chapter, you learned that: An attribute is a declarative tag that is used to convey information to runtime about the

behavior of programmatic elements such as classes, enumerators, and assemblies. The .NET Framework supports two categories of attributes to be used in C# programs:

predefined and custom. Predefined attributes are supplied as part of the CLR, and they are interpreted into .NET

Custom attributes are attributes that you create according to your requirement. The element to which you attach an attribute is called an attribute target. Reflection is used in the process of obtaining type information at runtime. Reflection is generally used for the following tasks

o Viewing metadatao Performing type discoveryo Late binding to methods and propertieso Reflection emit

Exercises

Exercise 1

Merge the Bugs Fixing attribute and Class description attribute together in a single application and use reflection to retrieve data from the same.

Chapter 14

Introduction to .NET Framework

The .NET Framework enables you to create robust and scalable applications. The .NET Framework consists of Common Language Runtime, Common Language Specification, and the Just-In-Time compiler.

Before you can use Visual Studio .NET for creating a console-based application, you need to understand the .NET Framework and the Visual Studio .NET Integrated Development Environment.

This chapter introduces the features and components of the .NET Framework. It explains the process of creating and executing a console application in the Visual Studio .NET IDE.

Page 195: C#

Objectives

In this chapter, you will learn to Identify the components of the .NET Framework Use the Visual Studio .NET IDE

Identifying the Components of the .NET Framework

Microsoft introduced the .NET Framework with the intention of bridging the gap in interoperability between applications. This framework aims at integrating various programming languages and services. It is designed to make significant improvements in code reuse, code specialization, resource management, Multilanguage development, security, deployment, and administration. It consists of all the technologies that help in creating and running robust, scalable, and distributed applications. This suite consists of the .NET Products, .NET services and .NET Framework:

.NET Products: Microsoft has already introduced Visual studio .NET, which is a tool for developing .Net applications by using programming languages such as Visual Basic, Visual C# and Visual C++.

These products aim at following developers to create applications, which are capable of interacting seamlessly with each other. To ensure interaction between various applications, all .NET products use eXtensible Markup Language (XML) for describing and exchanging data between applications

Note:XML is a platform independent markup language. It allows computers to store data is a format, which can be interpreted by any other computer system. therefore, XML can be used to transfer structured data between heterogeneous systems. XML is used as a common data interchange format in a number of applications.

.NET Services: .NET helps you to create software as Web Services. A Web Services is an application or business logic that is accessible through standard Internet protocols such as Hypertext Transfer Protocol (HTTP) and Simple Object Access Protocol (SOAP). You can identify the service by a Uniform Resource Locator (URL). Its public interfaces and bindings are described using XML. Therefore, users can subscribe to such a service and use it as long as they need it, regardless of the hardware and software platform.Microsoft has come up with its own set of Web Services, known as My Services. These Services are based on the Microsoft Passport Authentication service, which is used in their web applications such as Hotmail. This services allows users to access data by linking calendars, phonebooks, address books, and personal references to the passport authentication serviceIn addition, third party products and services can be integrated easily with the .NET environment.

.NET Framework: It is a foundation on which you design, develop and deploy applications. It is consistent and simplified programming model that helps you to easily build robust applications. It is the core of the .NET infrastructure because it exists as a layer between the .NET applications and the underlying operating system. In other words, the .NET Framework encapsulates much of the basic functionality, such as debugging and security services, which was earlier built in various programming languages, in the form of a collection of services and classes

Components of the .NET Framework

The following figure shows the various components of the .NET Framework.

Page 196: C#

The .NET Framework consists of three main components: Common Language Runtime, .NET Framework Base classes and the user and program interfaces.

Common Language Runtime (CLR)

The CLR is one of the most essential components of the .NET Framework. CLR is the environment where all programs using .NET technologies are executed. It provides services such as code compilation, memory allocation, and garbage collection. The CLR allows the execution of code across different platforms by translating code into Intermediate Language (IL). IL is low level language that the CLR understands.

IL is converted into machine language during execution by the Just-In-Time (JIT) compiler. During JIT compilation, code is also checked for type safety. Type safety ensures that objects are always accessed in a compatible way. If you try to assign an 8-byte value to a variable of size of 4 bytes, the CLR will detect and trap such an attempt, CLR consists of a set of common rules followed by all the languages of the .NET Framework. This set of rules is known as Common Language Specification (CLS). CLS enables an object or application to interact with the objects or applications of other languages. The classes that follow the rules specified by CLS are termed as CLS-complaint classes. The classes defined in the .NET Framework class library are CLS-compliant.

One of the specifications defined in CLS is Common Type System (CTS), which provides a type system that is common across all languages. CTS define how data types are declared, used and managed in the code at run-time.

The CTS also defines the rules that ensure that the data types of objects written in various languages are able to interact with each other. For example, the size of integer and long variables is the same across all CLS-complaint programming languages.

While executing the program, CLR plays an important role.

Identifying the Process of Compilation

Compilation is the process of creating an executable program from a source code. The source code consists of instructions for the compiler, and an executable program consists of instructions for the processor. Therefore, compilation converts source code to machine language.

Windows Forms Console Applications Web Forms & Web Services

.NET Framework Base Class Libraries

Common Language Runtime

Page 197: C#

However, when you compile a program in .NET, the conversion of source code to machine language happens in two stages. In the first stage, the compiler translates code into an IL. In addition, during the process of compilation, the compiler also produces metadata about code, such as classes and interfaces, dependencies and the versions of the components, used in the application. IL and metadata constitute an assembly.

Assemblies contain metadata, which describe the assembly’s internal version number and details of all the data and object types they contain. When you compile a VC# application, Visual Studio .NET creates an assembly that is a single file with the extension .exe and .dll. Assemblies can also contain one or more modules. For example, larger game projects may be planned in such a way that several individual developers to work on separate modules, all creating a single assembly.

The following figure shows the process of code compilation.

Identifying the Process of Code Execution

During execution, CLR performs the following steps: Loading assemblies and identifying namespaces: Assemblies are loaded in the memory.

After loading assemblies, CLR identifies namespaces for code in assemblies. Namespaces are a collection of classes. The .NET Framework uses namespaces to organize its classes in a hierarchy. Namespaces implicitly have public access and this cannot be changed.

JIT compilation: Before execution, IL is converted into machine language by the JIT compiler. Next, during the verification process, the IL code is examined to confirm the following points:

o The memory locations that code needs to access are availableo Methods are called only through properly defined typeso IL has been correctly generated

Garbage Collection: The garbage collection process begins after the JIT compilation and manages the allocation and de-allocation of memory for an application. Whenever you create an object, the CLR allocates memory for the object from the managed heap. A managed heap is a region of the memory that is available for program execution. If sufficient memory is not available on the managed heap, the garbage collection process is invoked.

The code developed in .NET is called managed code. The CLR manages the compilation and execution of the managed code to ensure proper functioning of the code. For example, the CLR takes care of garbage collection, exception handling, and type safety for the managed code.

Program Code

IL Metadata

Assembly

+

Compile

Page 198: C#

The unit of execution in the CLR is an assembly. An assembly contains IL and metadata that was generated during compilation. It contains code that the CLR executes. All assemblies contain a manifest, which contains information such as assembly name, version, and the list of files that form the assembly. The IL code cannot be executed if it does not have an associated assembly.

Instead of compiling the complete IL code, the JIT compiler compiles only the code that is required during execution. It saves the time and memory required to convert the complete IL into machine language.

The following figure shows the process of code compilation and execution.

In the preceding figure, two methods are shown, SetTopScore() and IgnoreScore(). The SetTopScore() method will be invoked only if the current score of the player is higher than the top score of the game. The IgnoreScore() method will be invoked when the player is not the top scorer and you do not want to add the player to the list of top scorers.

If the player has scored more than the top score, only the method SetTopScore() will be invoked. When it is invoked, the code for the SetTopScore() method will be compiled by the JIT compiler.

SetTopScore()

IgnoreScore()______________________________________________________

_

SetTopScore()

IgnoreScore()______________________________________________________

_

Visual C# code IL code

Code Compilation

IL code Machine Language

JIT

SetTopScore() invoked

Code Execution

SetTopScore()

IgnoreScore()______________________________________________________

_

SetTopScore()

Page 199: C#

However, the code for the method IgnoreScore() will not be converted to machine language by the JIT compiler because this method is not invoked.

The .NET Framework Class Library

The .NET Framework class library works with any .NET language, such as VB.NET, VC++ .NET, and VC#. This class library is built on the object-oriented nature of the runtime. The library provides classes that can be used in the code to accomplish a range of common programming tasks, such as string management, data collection, database connectivity, and file access.

One of the most important features of the .NET Framework class library is that it can be used in a consistent manner across multiple languages. This means that you can use the same set of classes for performing a specific task in VC# as well as in VC++.

The .NET Framework class library comprises namespaces, which are contained within assemblies. Let us look at what these two terms mean.

Namespaces

Namespaces help you create logical groups of related classes and interfaces, which can be used by any language targeting the .NET Framework. Namespaces allow you to organize your classes so that they can be easily accessed in other applications. Namespaces can be used to avoid any naming conflicts between classes, which have the same names. For example, you can use two classes with the same name in an application provided they belong to different namespaces.

You can access the classes belonging to a namespace by simply importing the namespace into the application. The .NET Framework uses a dot(.) as a delimiter between classes and namespaces. For example, System.Console represents the Console class of the System namespace. Namespaces are also stored in assemblies.

Assemblies

An assembly is a single deployable unit that contains all the information about the implementation of classes, structures, and interfaces. The assembly stores all the information about itself. This information is called metadata and includes the name and version number of the assembly, security information, information about the dependencies, and a list of the files that constitute the assembly.

All the applications developed using the .NET Framework are made up of assemblies. Assemblies and the metadata provide the CLR with the information required for executing an application. For example, if an application uses a component, the assembly keeps track of the version number of the component used in the application. The assembly provides this information to the CLR while the application is being executed. Assemblies also play an important role in deployment and versioning.

User and Program Interfaces

At the presentation layer, .NET provides three types of user interfaces. They are Windows Forms, Web Forms, and console Applications. Window Forms are used in Windows-based applications, whereas Web Forms are used in Web-based applications for providing an interactive user interface. They provide a Web browser-based user interface. You can create character based console applications that can be executed from the command line.

.NET provides a program interface, Web services, to communicate with remote components.

Advantages of the .NET Framework

Page 200: C#

Some of the advantages offered by the .NET Framework are: Consistent programming model: The .NET Framework provides a common OOPs

model across languages. This object model can be used in the code to perform several tasks, such as reading from and writing to files, connecting to databases, and retrieving data.

Multi-platform applications: There are several versions of Windows most of which run on x86 CPUs. Some versions, such as Windows CE and 64-bit windows, run on non-x86 CPUs as well. A .NET application can execute on any architecture that is supported by the CLR. In future, a CLR version could even be built for non-windows platforms.

Multi-language integration: .NET allows multiple languages to be integrated. For example, it is possible to create a class in VC# that derives from a class implemented in VB.NET. To enable objects to interact with each other regardless of the language used to develop them, a set of language features has been defined in CLS.This specification includes the basic language features required by many applications. The CLS enhances language interoperability. The CLS also establishes certain requirements, which help you to determine whether your managed code conforms to the CLS. Most of the classes defined in the .NET Framework class library are CLS-complaint.

Automatic resource management: While creating an application, a programmer may be required to write code for managing resources such as files, memory, network connections, and database resources. If a programmer does not free these resources, the application may not execute properly. The CLR automatically tracks resource usage and relieves a programmer of the task of manual resource management.

Easy of deployment: One of the goals of the .NET Framework is to simplify application deployment. .NET applications can be deployed simply by copying files to the target computer. Deployment of components has also been simplified. Till now, Microsoft’s Component object model (COM) has been used for creating components. However, COM suffers from various problems relating to deployment. For example, every COM component needs to be registered before it can be used in an application.Moreover, two versions of a component cannot run side-by-side. In such a case, if you install a new application that installs the newer version of the component, the newly installed application may function normally. However, the existing applications that depend on the earlier version of the component may stop functioning. As against this, the .NET Framework provides zero-impact deployment. Installation of new applications or components does not have an adverse effect on the existing applicationsIn the .NET Framework, applications are deployed in the form of assemblies. An assembly stores metadata. Therefore, registry entries are not required for storing information about components and applications. In addition, assemblies are store information about the versions of components used by an application. Therefore, the problems relating to versioning are also eliminated in the .NET Framework.

Using the Visual Studio .NET IDE

The Visual Studio .NET IDE provides you with a common interface for developing various kinds of projects for the .NET Framework. The IDE also provides you with a centralized location for designing the user interface for an application, writing code and compiling and debugging the application.

The Visual Studio .NET IDE is available to all the programmers who use languages in the Visual Studio .NET suite. Before you start using Visual Studio .NET for creating VC# applications, you need to know the various components of the Visual Studio .NET IDE.

Creating Projects and Solutions

Page 201: C#

In Visual Studio .NET, an application can be made up of one or more items, such as files and folders. To organize these items efficiently, Visual Studio .NET has provided 2 types of containers: projects and solutions.

A project typically contains items that make up the application. These items are interrelated. A project allows you to manage, build, and debug the items that make up an application. When you build a project, it usually results in the creation of an executable .exe or .dll files. These files that are created as a result of building the project are called the project output.

A solution usually acts as a container for one or more projects. For example, you may create a solution containing two projects, one for manipulation of data and the other for generation of reports for the sales division of an organization. Thus, a solution allows you to work on multiple projects within the same instance of the Visual Studio .NET IDE.

A solution containing multiple projects is shown in the following figure.

To create a console application in Visual Studio, you need to create a project. To create a project, you need to perform the following steps:

1. Select Start All Programs Microsoft Visual Studio 2005 Microsoft Visual Studio 2005. The Start Page – Microsoft Visual Studio window will be displayed.

2. Select File New Project. The New Project dialog box will be displayed.3. In the New Project dialog box, select Visual C# from the Project Types pane and

Console Applications from the Templates pane

There are many templates available in the Templates pane for a Visual C# project. You can select any one template described in the following table.

Template DescriptionWindows Application Creates an application with Windows user interfaceClass Library Creates a class or a reusable component that exposes some

functionality to be used in various projectsWindows Control Library Creates a custom control that can be added to the user interfaceConsole Application Creates a console application that can run from the command

Project 1

Project 2

Miscellaneous Files

Solution Project 1 Items

Project 1 Items

Solution Containing Multiple Projects

Page 202: C#

line. A console application has a command line interfaceDevice Application Creates a forms application for Pocket PC 2003 and laterCrystal Reports Application Adds a Windows user interface and a sample crystal Report in

the Visual C# application.

4. Specify the name of the application in the Name text box.5. Specify a location where the new project is to be created in the Location combo box.

You can use the Browse button to browse to the folder in which the new project is to be created.

6. Click the OK button.

User Interface Elements of Visual Studio .NET IDE

When you work with a console application project in Visual Studio .NET, you can use the following main elements in the Visual Studio .NET IDE.

Various standard interface elements are found in the Windows environments, such as the menu bar and the tool bar. In addition to these standard interface elements, the Visual Studio .NET IDE contains other elements. These include the Solution Explorer window, Output window, Task List window, Class View window and the Code Editor window.

In addition, Visual Studio .NET provides the Start Page and the Project properties window. The Start Page allows you to perform several tasks and the Project Properties helps you to set the projects compilation and configuration values.

Standard Toolbar

The standard toolbar is located below the menu bar. It provides shortcuts for menu commands. The first few buttons of the toolbar enable you to perform tasks common to many Window-based programs, such as opening a new or an existing file, saving or printing a file, cutting and pasting text and objects, and undoing or redoing the most recent actions. Other standard toolbar buttons offer functions more specific to Visual Studio .NET applications. The name and functions of the various tools of the standard toolbar are listed in the following table.

Name FunctionNew Creates a new projectAdd New Item Add new item to the projectSave Saves the programSave All Save all the unsaved items of the applicationCut Places selected text or objects on the Windows

ClipboardCopy Places a copy of selected text or objects on the

Windows ClipboardPaste Pastes the contents of the clipboard on the

documentStart Debugging Compiles and executes the current project

The Start Page

When you start Visual Studio .NET, it displays the Start Page – Microsoft Visual Studio window.

The Start Page is the default home page for the browser provided within the Visual Studio .NET IDE. This allows you to perform several tasks, such as specifying your preferences, searching for

Page 203: C#

information on the new features of .NET, communicating with developers working on the .NET platform, and searching for more information in the MSDN Online Library.

When you open Visual Studio .NET, the projects tab on the Start Page is selected by default. This tab displays some of the recent projects and the last date of their modification. You can open any one of these projects. If the project that you wish to work on is not listed, click the Open Project button on the Start Page. If you wish to start with a new project, you can click the New Project button on the Start Page.

The Solution Explorer

The Solution Explorer window lists the solution name, the project name, and all the classes that are used in the project. You can open a particular file existing in a project by double-clicking the file in the solution explorer window.

The Output Window

The Output Window displays messages for the status of various features provided in the Visual Studio .NET IDE. For example, when you compile an application, this window displays the current status. After the compilation process is complete, it specifies the number of errors that occurred during compilation. If this window is not visible, you can open it by selecting View Output Window by pressing the Ctrl+W, O keys simultaneously.

The Error List Window

The Error List Window displays a list of errors along with the source (the file and the line number) of the error. It helps you identify and locate problems that are detected automatically as you edit and compile code. You can locate the source of a particular error by simply double-clicking the error in the Error List Window. Alternatively, you can press the Ctrl+W, E keys simultaneously.

The Class View Window

The Class View Window displays the classes, methods, and properties associated with a particular file. They are displayed in a hierarchical tree-view depicting the containership of these items. When you double-click any one of the items in the Class View window, it brings up the Code Editor window for that item, making it convenient to move through the code in the project.

The Class View Window has two buttons, one for sorting the items in the Class View Window and the other for creating a new folder. If the class view window is not visible, you can open it either by selecting View Class View or by pressing the Ctrl+Shift+C keys simultaneously.

The Code Editor

The Code Editor allows you to enter and edit code. You may use this editor to add code for you class.

Compiling and Executing Project

To compile and execute the application, you need to perform the following steps:1. Select Build Build Solution or press F6 to compile the application.2. Select Debug Start Debugging or press F5 to execute the application.

Practice Questions

1. What is Just-In-Time compilation?

Page 204: C#

2. Which CLR feature ensures that data types are accessible across different applications?

3. What is project output?

4. Which Visual C# template allows to create a custom control that can be used in a GUI game?

a. Windows Control Library b. Device Applicationc. Class Libraryd. Crystal Reports Application

5. You need to select the option from the debug menu to execute a game developed in Visual Studio .NET

6. State whether the given statement is True or FalseJIT compilation saves time and memory required to convert the complete IL into machine language

Summary

In this chapter, you learned that: The .NET Framework is made up of many components, such as CLS, CLR, and JIT

compiler. CLS is a set of rules that are followed by all the languages of the .NET Framework. When a program is compiled using Visual Studio .NET the compiler translates the code

into the IL instead of machine language. The JIT compiler is used to translate code from IL into machine language The CLR is the environment where all .NET applications are executed. The Visual Studio .NET IDE provides you with a common interface for developing various

kinds of applications for the .NET Framework Visual Studio .NET provides 2 types of containers, projects and solutions, to organize the

constituents of an applications.


Recommended