learn c# marathi transliteration
DESCRIPTION
Learn C# Text - Project to translate it in Marathi languageTRANSCRIPT
1 | P a g e
सी शाप�अगद सोप ंभाषेत
कौसरकौसरकौसरकौसर चुनावालाचुनावालाचुनावालाचुनावाला
शाप� �शकुयाभाषेत
See the output for yourself
Write the
program
Get the gist of the concept
�शकुया
2 | P a g e
Learn C# - do it yourself way... 2008
संगणकशा�ा�या �व ा!या"साठ$
These notes were compiled by me, while serving NIIT Training
Institute, Mumbai – India as a faculty member. This text would
facilitate the learning process of the students when they learn an
Object-Oriented Programming language like C#. It starts from scratch
and takes you upto the depth required at an undergraduate school. I
appreciate the contribution made by my students – Farzan, Mario,
Swapnil, Geetashree, Swati, Pooja, Shraddha, Chaitali, Snehal,
Sushil, Anand, Sadiq, Rama, Tausif, Ameya and all other students and
colleagues.
Program Listing
Chapter Name Pages
3 | P a g e
Learn C# - do it yourself way... 2008
1 Introduction to C#
2 C# Fundamentals
3 Decision Making and Looping Constructs
4 Classes, Objects and Methods
5 Collections in C#
6 Polymorphism, Constructors and
Destructors
7 Inheritance – Our objects’ family tree
8 Advanced C# Language Concepts
9 File Input and Output
10 Exception Handling
11 Threads
12 Attributes and Reflections
1 | P a g e
1
Introduction to C#
1.1 Hello World C# Style
using System;
class Greeting
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World");
}
}
Output :
1. Open the Notepad and type
the following
program.
2. Save the file as Hello.cs
3. Go to Visual Studio Command
Prompt from Start->
All Programs - >Visual
Studio 2008 -> Visual
Studio Tools
4. On the command prompt, go
to the directory,
where you saved the
file.
5. Type cs Hello.cs to compile
the program.
6. Type Hello to run the
program.
2 | P a g e
Learn C# - do it yourself way... 2008
Dissecting the Hello World Program
using System;
class Greeting
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World");
}
}
The program starts with the using statement. Wait for a while, till I
tell you what it means. Then, we declare a class called Greeting. All
code in C# must be written inside a class.
Next, we have written Main(). The word Main() indicates this is the
start of the program. This is where the C# system start the
executing(running) the program. Thus, Main() is the entry
point(starting point) of any program. All statements written inside
Main() are executed line by line. The Main() block is started using a
starting curly brace { and terminated using an ending curly brace }.
Whatever you want to write inside Main() must be enclosed within
this pair of curly braces. On the same lines, whatever you write inside
the class, must be enclosed within { ... }.
In the above program, we have written just one command/statement –
Console.WriteLine().This command is used display text on the VDU
screen. Whatever you put inside Console.WriteLine() gets printed on
the screen, when you run the program. In this case, it is Hello World.
3 | P a g e
Learn C# - do it yourself way... 2008
What are Classes and Objects?
C# is an object-oriented programming language. All the C# code you
write will appear in a class.
In early days of programming, programs were designed using
flowcharts and a sort of top-down design. With this type of design, a
large problem was solved step-by-step. Thus, the solution to a
problem was visualised as a series of steps or operations. To arrive at
the solution, you follow the sequence of steps or procedure. This form
of programming is called Procedural Programming.
The new paradigm of programming is Object-Oriented Programming.
In Object-Oriented Programming, to find the solution, we decompose
a large problem in terms of objects.
So, what really are objects. Any real world entity or thing, say for
example a car, a person, a flight, a ticket-booking, an employee, a
college can be an object in C#. To model real world things, in C# we
create objects.
Just like in the real – world, each object has some features or
characteristics that describe the object, our C# objects also have
features that describe the object. For example, every car has some
name, brand, year of manufacture, price, color which describe it. In
C#, to model this concept, C# car object will also have attributes
name, brand, yearOfManufacture, price, color etc. Every car object
will have its own values of these attributes. Consider the following
two car objects –
4 | P a g e
Learn C# - do it yourself way... 2008
6
Polymorphism, Constructors
and Destructors
6.1 Function Overloading
class Test
{
public int Multiply(int a, int b)
{
return a * b;
}
public double Multiply(double a, double b)
{
return a * b;
}
public double Multiply(int a, double b)
{
return a * b;
}
public double Multiply(double a, int b)
{
return a * b;
}
public int Multiply(int a, int b, int c)
{
return a * b * c;
}
}
class OverloadDemo
{
public static void Main()
{
Test t = new Test();
double res1 = t.Multiply(4.2, 5.5);
int res2 = t.Multiply(3, 5);
double res3 = t.Multiply(4.2, 5);
There are 6 different versions of the
Multiply() method in the Test class.
The 1st
version multiplies two ints
and returns an int as the answer.
The 2nd
version accepts 2 doubles as
input parameters and returns a
double result as the answer. The 3rd
version accepts an integer and a
double number as an argument, and
returns their product as the answer.
Every time, we are assigning a new
extra meaning to the Multiply()
function. Thus, we have overloaded
the Multiply() method.
5 | P a g e
Learn C# - do it yourself way... 2008
double res4 = t.Multiply(5, 3.8);
int res5 = t.Multiply(3, 4, 5);
}
}
In method overloading, we assign a new extra meaning to the method.
For example suppose, we have written the Multiply() method as
follows :
public int Multiply(int x, int y)
{
int result = x * y;
return result;
}
The Multiply() method is designed to accept 2 integers as input
parameters. It multiplies the two integers x and y, and returns an
integer result as the answer.
Suppose, we now define one more Multiply() method as follows -
public double Multiple(double x, double y)
{
double result = x * y;
return result;
}
This Multiply() method multiplies two double numbers and returns a
double result as the answer. Thus, the Multiply() method now has two
different versions. The first version can multiply two integers,
whereas the second version can multiply 2 doubles. Thus, we have
assigned a new extra meaning to the Multiply() method, so that it can
now no longer multiply just two ints, but it can as well multiply two
doubles.Hence, we have overloaded the Multiply() method. Thus, this
is method overloading.
Let us define one more Multiply() method as follows -
6 | P a g e
Learn C# - do it yourself way... 2008
public double Multiply(int x, double y){
double result;
result = x * y;
return result;
}
This time round, the Multiply() method can multiply one int with one
double value, and returns a double result as the answer. Thus, we are
again assigning a new extra meaning to the Multiply() method. So,
once again we have overloaded the Multiply() function.
If we define one more Multiply() method as :
public double Multiply(double x, int y)
{
double result;
result = x * y;
return result;
}
This new version of the Multiply() method can now multiply a double
with an integer. Mutiplying a double with an int, is different from
multiplying an int with a double.
Thus, we are again assigining a new meaning to the Multiply()
method. Hence, we have again overloaded the Multiply() method.
Consider another version of the Multiply method -
public int Multiply(int x, int y, int z){
return x * y * z;
}
This version of the Multiply() method computes the product of 3 ints
instead of 2. Once again we have assigned extra meaning to
Multiply(). So, it is an overloaded function.
A function is said to be overloaded if -
7 | P a g e
Learn C# - do it yourself way... 2008
1. When two or more methods in the same class have the same name
2. They have different Parameter Lists
Parameter list is different if -
- Type of parameters differs.
- No of parameters is different.
- Order of parameters is different.
6.2 Operator Overloading
class Date
{
public int day;
public int month;
public int year;
public static Date operator +(Date d1, Date d2)
{
Date result = new Date();
result.day = d1.day + d2.day;
result.month = d1.month + d2.month;
result.year = d1.year + d2.year;
if(result.day>30){
result.day -= 30;
result.month++;
}
if (result.month > 12)
{
result.month -= 12;
result.year++;
}
return result;
}
public static bool operator <(Date d1, Date d2)
{
bool ans;
int days1 = d1.day + d1.month * 30 + d1.year *
365;
int days2 = d2.day + d2.month * 30 + d2.year *
365;
if (days1 < days2)
ans = true;
else
ans = false;
return ans;
}
public static bool operator >(Date d1, Date d2)
A Date class is used to represent the
date in the form of days, months
and years.
The + operator is overloaded, so that
it can add two Date class objects.
The two Date objects are passed as
arguments into d1 and d2. To store
the sum of Date objects, we take a
result Date object. We set the day,
month and year of the result Date
object as the sum of the
corresponding day, month and year
of d1 and d2.
We also need to check for overflow.
Overflow happens when the no of
resulting days exceeds 30. For
example, we treat 35 days as 1
month and 5 days. So, when an
overflow occurs we add 1 to the
months, and the balance days are 35
– 30 = 5.
The < operator is overloaded, so that
it can compare 2 Date objects and
find out which is smaller. Comparing
2 Date objects for the no. Of days,
months and years can be tricky, so a
simple way would be to find the
total no of days of each Date object
and then just compare them. If
days1 turns out to be less than
days2 as assumed, return true else
return false. We also overload >
operator, since they must be
overloaded in pairs.
8 | P a g e
Learn C# - do it yourself way...
{
bool ans;
int days1 = d1.day + d1.month * 30 + d1.year * 365;
int days2 = d2.day + d2.month * 30 + d2.year * 365;
if (days1 > days2)
ans = true;
else
ans = false;
return ans;
}
public void GetDate()
{
Console.WriteLine(
Console.WriteLine(
Console.WriteLine(
Console.WriteLine();
}
}
class DateDemo
{
public static void Main()
{
Date d1 = new Date
Date d2 = new Date
Date result;
bool ans;
d1.day = 2;
d1.month = 7;
d1.year = 5;
d2.day = 29;
d2.month = 6;
d2.year = 4;
result = d1 + d2;
d1.GetDate();
d2.GetDate();
result.GetDate();
ans = (d1 > d2);
Console.WriteLine(
}
}
Suppose we write the instruction 2 + 3.
days1 = d1.day + d1.month * 30 + d1.year * 365;
days2 = d2.day + d2.month * 30 + d2.year * 365;
(days1 > days2)
;
GetDate()
.WriteLine("Day : " + day);
.WriteLine("Month : " + month);
.WriteLine("Year : " + year);
.WriteLine();
Main()
Date();
Date();
result = d1 + d2;
result.GetDate();
s = (d1 > d2);
.WriteLine("d1 > d2 : " + ans);
Suppose we write the instruction 2 + 3.
2008
9 | P a g e
Learn C# - do it yourself way... 2008
When the C# system encounters this line, it does not directly add the
2 + 3. Instead, the C# system calls a function with the name + and
passes 2 and 3 as the arguments.
+(2,3)
When this function is called, the control jumps to the function
definition. The + function looks like this
public int operator +(int a, int b)
{
___________________;
___________________;
___________________;
}
Since, the computer gives us the answer of 2 + 3 = 5, this function +
is already defined in C#. Now, suppose we would like to assign extra
meaning to the + operator.
Let's say we have the following objects -
MyClass obj1 = new MyClass();
MyClass obj2 = new MyClass();
Suppose, we now write
obj1 + obj2
Thus, the following function is called -
+(obj1,obj2)
But, since these our own objects, we have created them, we have
made their class design, the + operator does not know how to add
these custom made objects. To be able to add them, we need to define
the following function -
10 | P a g e
Learn C# - do it yourself way... 2008
public MyClass operator + (MyClass obj1, MyClass obj2){
MyClass result;
//Code for adding the 2 objects..
_______________________________;
_______________________________;
return result;
}
By defining this function, the + operator will also be able to add
objects. Hence, we are assigning extra meaning to the + operator, so
that it is able to add our own objects. Hence, it is called Operator
Overloading.
Syntax for Overloading Binary Arithmetic Operator
public static MyClass operator + (MyClass obj1, MyClass obj2)
{
MyClass result;
______________
______________
return result;
}
Syntax for Overloading Unary Arithmetic Operator
public static MyClass operator -(MyClass obj)
{
MyClass result;
______________
______________
return result;
}
11 | P a g e
Learn C# - do it yourself way... 2008
Syntax for Overloading Relational Operators
public static bool operator <(MyClass obj1, MyClass obj2){
bool ans;
//Compare the two objects
______________
______________
return ans;
}
Note : Relational operators are always overloaded in pairs.
If we overload < operator, then we must also overload > operator.
Similarly, if we overload <= or == operator, we must also overload
their corresponding complementary operators >= and !=.
6.3 Constructors
class Box
{
double width;
double height;
double depth;
public Box()
{
width = height = depth = 1;
}
public Box(int l)
{
width = height = depth = l;
}
public Box(int w, int h, int d)
{
width = w;
height = h;
depth = d;
}
public void GetBox()
{
Console.WriteLine("w : " + width + " h : " + height + " d :
"+depth);
}
12 | P a g e
Learn C# - do it yourself way...
public void Volume()
{
Console.WriteLine(
}
}
class BoxDemo
{
public static void Main()
{
Box myBox1 = new
Box myBox2 = new
Box myBox3 = new
myBox1.GetBox();
myBox2.GetBox();
myBox3.GetBox();
myBox1.Volume();
myBox2.Volume();
myBox3.Volume();
}
}
A constructor is a special method that is called automatically, when
an object is created.
Why Constructors?
When we first create an object, all its fields are initialised to 0. In
other words, the memory is zeroed out.
Box myBox;
myBox = new Box();
To be able to use this Box object, we must put in meaningful values in
the width, height and depth of myBox. Thus, we must assign values to
myBox’s instance variables.
To do so, we must manually go in and initialise all the fields of the
myBox object.
Volume()
.WriteLine("Volume : " + width * height * depth);
Main()
new Box();
new Box(5);
new Box(10, 20, 30);
myBox1.GetBox();
myBox2.GetBox();
myBox3.GetBox();
myBox1.Volume();
myBox2.Volume();
myBox3.Volume();
A constructor is a special method that is called automatically, when
Why Constructors?
When we first create an object, all its fields are initialised to 0. In
other words, the memory is zeroed out.
Box myBox;
myBox = new Box();
To be able to use this Box object, we must put in meaningful values in
the width, height and depth of myBox. Thus, we must assign values to
myBox’s instance variables.
To do so, we must manually go in and initialise all the fields of the
2008
+ width * height * depth);
A constructor is a special method that is called automatically, when
When we first create an object, all its fields are initialised to 0. In
To be able to use this Box object, we must put in meaningful values in
the width, height and depth of myBox. Thus, we must assign values to
To do so, we must manually go in and initialise all the fields of the
13 | P a g e
Learn C# - do it yourself way...
myBox.width = 10;
myBox.height = 20;
myBox.depth = 30;
All of this seems rosy-
object. But, consider a real
keep track of thousands of orders and consignments. Each
consignment is shipped in Box object. So, if we typically have 1000
Box objects; myBox1, myBox2, myBox3,... this process of manually
initialising all the fields becomes very tedious and cumbersome.
Well, you can use convenience methods like SetBox(). Bu
have a thousand objects, you have explicitly call/invoke SetBox()
method on each Box object. Once again, it calls for a lot of work.
How can Constructors help me?
myBox.width = 10;
myBox.height = 20;
myBox.depth = 30;
-rosy till we have to work with just 1 Box
object. But, consider a real-time shipping application, where we to
keep track of thousands of orders and consignments. Each
ignment is shipped in Box object. So, if we typically have 1000
Box objects; myBox1, myBox2, myBox3,... this process of manually
initialising all the fields becomes very tedious and cumbersome.
Well, you can use convenience methods like SetBox(). Bu
have a thousand objects, you have explicitly call/invoke SetBox()
method on each Box object. Once again, it calls for a lot of work.
How can Constructors help me?
2008
rosy till we have to work with just 1 Box
time shipping application, where we to
keep track of thousands of orders and consignments. Each
ignment is shipped in Box object. So, if we typically have 1000
Box objects; myBox1, myBox2, myBox3,... this process of manually
initialising all the fields becomes very tedious and cumbersome.
Well, you can use convenience methods like SetBox(). But, when you
have a thousand objects, you have explicitly call/invoke SetBox()
method on each Box object. Once again, it calls for a lot of work.
14 | P a g e
Learn C# - do it yourself way... 2008
Constructor is a special method that is invoked automatically, when
an object is created. So, you don’t have to call a constructor method
explicitly.
Thus, constructor can be used to automatically initialise an object,
right at the time when the object is born/created.
1. A constructor has the same name as the class.
2. Like methods, constructors can also accept input parameters.
3. Unlike methods, constructors do not have a return type, not even
void.
4. Like methods, constructors can also be overloaded. Depending
upon the call, different versions of the constructor will be invoked.
Note – Adding constructors to a class is compulsory.
Q. But, the classes that we have written till now seemed to work fine
without a constructor.
A. If you do not write your own constructor, the C# Compiler adds a
constructor method for you for free. Such a constructor is called the
default constructor.
Q. But how does the default constructor know, what I want it to do?
A. It does not! That’s why, it does not accept any parameters and has
empty body. It looks like this –
public Box()
{
}
Thus, the free constructor that C# compiler adds for you, is a do-
nothing constructor.
15 | P a g e
Learn C# - do it yourself way... 2008
6.4 Destructors, Finalize() and
Dispose()
We know that when, objects are created, constructors are called, but
when objects are destroyed what happens?
Unlike C C++, in C# you don’t have to manually destroy objects.
Objects which are no longer needed are automatically destroyed by
the Garbage Collector(GC).
In C#, you can have two kinds of resources in the programs you write.
The Objects of a class, primitive data-types etc. are supported by C#,
and the space occupied by them is automatically release by the GC,
when it finds they are no longer in use. Such resources are called
Managed Resources.
But, there are other resources, like a Database Connection, a File
Stream, a Network Stream, a pipe etc. which are not supported by C#.
This means, when they are no longer in use, the responsibility of their
clean-up does not lie with the GC. You have to make sure, you clean
up these resources. Such resources are called unmanaged resources.
If your program/class uses unmanaged resources, you can clean up
these resources in two ways –
1)Write a destructor or finalizer method.
2)Override the Dispose() method.
If you write a destructor in the class, it is called just before the objects
of this class are destroyed by GC. There are two ways to write a
destructor –
class MyClass
{
~MyClass()
{
Console.WriteLine("You can free up an unmanaged resources here.");
}
}
16 | P a g e
Learn C# - do it yourself way... 2008
class DestroyDemo
{
public static void Main()
{
MyClass obj = new MyClass();
obj = null;
}
}
A destructor has the same name as the class, but prefixed with a ~
tilde sign. Internally, this Destructor is translated to a call to the
Finalize() method –
class MyClass
{
protected override void Finalize()
{
try
{
Console.WriteLine("You can free up any unmanaged resources
here");
}
finally
{
base.Finalize();
}
}
}
Now, when you have a number of objects, the order in which these
objects will be destroyed/finalized is not fixed or known. Say, if we
have five objects obj1, obj2, obj3, obj4, obj5 of a class MyClass. The
GC may decide to destroy the objects in any random order say, for
example obj3, obj5,obj1, obj4, obj2. The GC maintains a queue of all
the objects that are to be finalized. This is called Finalization Queue.
In other words, finalization is non-deterministic(random). When we
want to exercise control over the finalization process, we can override
the Dispose() method (whose interface is IDisposable). The Dispose()
method differs from the Finalize() method, in that, we need to
explicitly call the Dispose() method. A finalizer is implicitly called,
and cannot be explicitly called, even if you wanted to.
Implicit Resource Cleanup Destructor or Finalize() method
Explicit Resource Cleanup Dispose()
17 | P a g e
Learn C# - do it yourself way... 2008
7
Inheritance – Our objects’
family tree
7.1 Overview of Inheritance
Kathy is assigned the task of building an Employee Management
System. She starts by thinking, “I am gonna take Employee objects
for every Employee” in the organisation. So, she begins by writing an
Employee class as follows –
class Employee
{
public string name;
public string address;
public int SSN;
public int number;
public float salary;
public float computePay()
{
return salary / 12.0F;
}
}
The design of an Employee class seems fine to her initially. An
employee has a name, address, and number and so on... We want the
compute the pay of different Employee objects.
But, Kathy questions herself, does every Employee have a salary? Is it
true that every Employee object has a salary. By studying the problem
18 | P a g e
Learn C# - do it yourself way... 2008
domain, she finds out that there are Employees which are paid on an
hourly basis, or employees which are on contract basis.
The first mistake Kathy made was to add a field of type salary to
Employee. She discovers although employees are the objects in our
problem domain, there are actually two different types of Employee
objects : Salaried Employees and Hourly Employees. Therefore, we
should write two classes : Salary and Hourly.
The Salary class should have a field to represent the employee’s
annual salary because a Salaried Employee has a salary. The Hourly
class should have fields to represent the employee’s hourly pay rate
and the no of hours for which he worked.
The Salary and Hourly classes look like this –
class Salary
{
public string name;
public string address;
public int SSN;
public int number;
public int salary;
public float computePay()
{
return salary / 12.0F;
}
}
class Hourly
{
public string name;
public string address;
public int SSN;
public int number;
public int hoursWorked;
public int hourlyRate;
public int computePay()
{
return hoursWorked*hourlyRate;
}
}
Although Salary and Hourly classes are different types, they are not
entirely different. In fact, the two types of employees have a lot in
common, as seen by the repetition of fields and methods in these two
19 | P a g e
Learn C# - do it yourself way... 2008
classes. So, we can take the common elements from both the classes,
and put them in a parent class leaving the unique elements behind in
the child class. We can simply make the Salary and Hourly classes
inherit the elements of the Employee class.
Employee class is called Parent class/Base class/Super class.
Salary and Hourly classes are called child class/Derived class/sub-
class.
If you want to make Salary and Hourly the child classes of Employee,
we write them as follows :
class Employee
{
public string name;
public string address;
public int SSN;
public int number;
}
class Salary : Employee
{
public int salary;
public float computePay()
{
return salary / 12.0F;
}
}
class Hourly : Employee
{
public int hoursWorked;
public int hourlyRate;
public int computePay()
{
return hoursWorked*hourlyRate;
}
} When your classes use inheritance, you only need to write your code once.
In the above scenario, Salary class and the Hourly class have a lot of
same code.
20 | P a g e
Learn C# - do it yourself way...
Salary Employee and Hourly Employee are both employees.
When you have two classes which are more specific cases of
something more general, you can set them up to inherit from the same
base class.
Build up your class model, by starting General and getting more Specif
7.2 Method Overriding
class Employee
{
public string name;
public string address;
public int SSN;
public int number;
Salary
salary
computePay()
and Hourly Employee are both employees.
When you have two classes which are more specific cases of
something more general, you can set them up to inherit from the same
Build up your class model, by starting General and getting more Specif
7.2 Method Overriding
address;
Employee
name
address
SSN
number
GetEmployee()
Hourly
hourlyRate
hoursWorked
computePay()
2008
and Hourly Employee are both employees.
When you have two classes which are more specific cases of
something more general, you can set them up to inherit from the same
Build up your class model, by starting General and getting more Specific
hoursWorked
computePay()
21 | P a g e
Learn C# - do it yourself way... 2008
public void GetEmployee()
{
Console.WriteLine("Name : " + name);
Console.WriteLine("Address : " + address);
Console.WriteLine("SSN : " + SSN);
Console.WriteLine("Number : " + number);
Console.WriteLine();
}
}
class Salary : Employee
{
public int salary;
public float computePay()
{
return salary / 12.0F;
}
public void GetEmployee()
{
Console.WriteLine("Name : " + name);
Console.WriteLine("Address : " + address);
Console.WriteLine("SSN : " + SSN);
Console.WriteLine("Number : " + number);
Console.WriteLine("Salary : " + salary);
Console.WriteLine();
}
}
class Hourly : Employee
{
public int hoursWorked;
public int hourlyRate;
public int computePay()
{
return hoursWorked * hourlyRate;
}
public void GetEmployee()
{
Console.WriteLine("Name : " + name);
Console.WriteLine("Address : " + address);
Console.WriteLine("SSN : " + SSN);
Console.WriteLine("Number : " + number);
Console.WriteLine("Hours Worked : " + hoursWorked);
Console.WriteLine("Hourly Rate : " + hourlyRate);
Console.WriteLine();
}
}
class EmployeeDemo
{
public static void Main()
{
Employee e = new Employee();
e.name = "Robert Smith";
e.address = "111 Palm street";
e.SSN = 999901111;
e.number = 1;
22 | P a g e
Learn C# - do it yourself way... 2008
Salary s = new Salary();
s.name = "Jane Smith";
s.address = "Oak Drive";
s.SSN = 111009999;
s.number = 2;
s.salary = 10000;
Hourly h = new Hourly();
h.name = "George Washington";
h.address = "333 Espresso Lane";
h.SSN = 111990000;
h.number = 3;
h.hoursWorked = 200;
h.hourlyRate = 30;
e.GetEmployee();
s.GetEmployee();
h.GetEmployee();
}
}
7.3 Use of base keyword
using System;
class Employee
{
public string name;
public string address;
public int SSN;
public int number;
public void GetEmployee()
{
Console.WriteLine("Name : " + name);
Console.WriteLine("Address : " + address);
Console.WriteLine("SSN : " + SSN);
Console.WriteLine("Number : " + number);
Console.WriteLine();
}
}
class Salary : Employee
{
public int salary;
public float computePay()
{
return salary / 12.0F;
}
public void GetEmployee()
{
base.GetEmployee();
Console.WriteLine("Salary : " + salary);
Console.WriteLine();
}
}
23 | P a g e
Learn C# - do it yourself way... 2008
class Hourly : Employee
{
public int hoursWorked;
public int hourlyRate;
public int computePay()
{
return hoursWorked * hourlyRate;
}
public void GetEmployee()
{
base.GetEmployee();
Console.WriteLine("Hours Worked : " + hoursWorked);
Console.WriteLine("Hourly Rate : " + hourlyRate);
Console.WriteLine();
}
}
class EmployeeDemo
{
public static void Main()
{
Employee e = new Employee();
e.name = "Robert Smith";
e.address = "111 Palm street";
e.SSN = 999901111;
e.number = 1;
Salary s = new Salary();
s.name = "Jane Smith";
s.address = "Oak Drive";
s.SSN = 111009999;
s.number = 2;
s.salary = 10000;
Hourly h = new Hourly();
h.name = "George Washington";
h.address = "333 Espresso Lane";
h.SSN = 111990000;
h.number = 3;
h.hoursWorked = 200;
h.hourlyRate = 30;
e.GetEmployee();
s.GetEmployee();
h.GetEmployee();
}
}
7.4 Adding Constructors
using System;
public class Employee
{
public string name;
public string address;
public int SSN;
24 | P a g e
Learn C# - do it yourself way... 2008
public int number;
public Employee()
{
Console.WriteLine("Inside Grandparent");
}
public void GetEmployee()
{
Console.WriteLine("Name : " + name);
Console.WriteLine("Address : " + address);
Console.WriteLine("SSN : " + SSN);
Console.WriteLine("Number : " + number);
Console.WriteLine();
}
}
public class Salary : Employee
{
public int salary;
public Salary()
{
Console.WriteLine("Inside Parent");
}
public float computePay()
{
return salary / 12.0F;
}
public void GetEmployee()
{
Console.WriteLine("Name : " + name);
Console.WriteLine("Address : " + address);
Console.WriteLine("SSN : " + SSN);
Console.WriteLine("Number : " + number);
Console.WriteLine("Salary : " + salary);
Console.WriteLine();
}
}
public class PartTimeSalary : Salary
{
public PartTimeSalary()
{
Console.WriteLine("Inside PartTimeSalary");
}
}
class EmployeeDemo
{
public static void Main()
{
PartTimeSalary pts = new PartTimeSalary();
}
}
7.5 Calling Parent class Constructors
25 | P a g e
Learn C# - do it yourself way... 2008
using System;
public class Employee
{
public string name;
public string address;
public int SSN;
public int number;
public Employee(string n, string a, int S, int num)
{
name = n;
address = a;
SSN = S;
number = num;
}
public void GetEmployee()
{
Console.WriteLine("Name : " + name);
Console.WriteLine("Address : " + address);
Console.WriteLine("SSN : " + SSN);
Console.WriteLine("Number : " + number);
Console.WriteLine();
}
}
public class Salary : Employee
{
public int salary;
public Salary(string n,string a, int S, int num, int
sal):base(n,a,S,num)
{
salary = sal;
}
public float computePay()
{
return salary / 12.0F;
}
public void GetEmployee()
{
Console.WriteLine("Name : " + name);
Console.WriteLine("Address : " + address);
Console.WriteLine("SSN : " + SSN);
Console.WriteLine("Number : " + number);
Console.WriteLine("Salary : " + salary);
Console.WriteLine();
}
}
class EmployeeDemo
{
public static void Main()
{
Salary s = new Salary("Jane Smith", "222 Oak Drive", 111009999, 3,
10000);
s.GetEmployee();
}
}
26 | P a g e
Learn C# - do it yourself way... 2008
8
Advanced C# Language
Concepts
8.1 Using Parent class references to
Child Objects
An object reference can refer to an object of its class, or to an object
of any class derived from it by Inheritance. Suppose, we have the
following class hierarchy.
For example, if Animal class is the parent, and Bird is its child,
SongBird is the child of Bird and so on,... Animal reference can refer
to a Bird object or a SongBird object.
Animal a;
27 | P a g e
Learn C# - do it yourself way... 2008
a = new Animal();
a = new Bird();
a = new SongBird();
Assigning an object to an ancestor reference is considered to be a
widening conversion, and can be performed using simple assignment.
Animal a = new MockingBird();
Assigning an ancestor object to a child reference can also be done, but
it is considered to be a narrowing conversion and must be done with a
cast.
MockingBird m = (MockingBird)new Bird();
The widening conversion is the most useful for implementing
polymorphism.
8.2 Polymorphism via Inheritance
A polymorphic reference is the one which can refer to different types
of objects at different times. Such an object reference can refer to one
object at one time, and can refer to another object(related by
inheritance) at another time.
It is the type of object being reference, not the reference type, which
determines which method is invoked. Polymorphic references are
therefore resolved at run-time, not during compilation; hence it is
called dynamic binding.
class Shape
{
public virtual void Area()
{
}
}
28 | P a g e
Learn C# - do it yourself way... 2008
class TwoDimShape : Shape
{
public int a;
public int b;
}
class ThreeDimShape : Shape
{
public int a;
public int b;
public int c;
}
class Rectangle : TwoDimShape
{
public override void Area()
{
int area = a * b;
Console.WriteLine("Area : " + area);
}
public void SetRectangle(int x, int y)
{
a = x; b = y;
}
}
class Triangle : TwoDimShape
{
public override void Area()
{
double area = 0.5 * a * b;
Console.WriteLine("Area : " + area);
}
public void SetTriangle(int bas, int height){
a = bas;
b = height;
}
}
class Cube : ThreeDimShape
{
public override void Area()
{
int area = 6 * a * a;
Console.WriteLine("Area : " + area);
}
public void SetCube(int s)
{
a = b = c = s;
}
}
class Box : ThreeDimShape
{
public override void Area()
{
int area = 2 * a * b + 2 * b * c + 2 * a * c;
Console.WriteLine("Area : " + area);
29 | P a g e
Learn C# - do it yourself way... 2008
}
public void SetBox(int x, int y, int z)
{
a = x;
b = y;
c = z;
}
}
class ShapeDemo
{
public static void Main()
{
int choice;
Shape s = new Shape();
Triangle t = new Triangle();
t.SetTriangle(5,10);
Rectangle r = new Rectangle();
r.SetRectangle(10,10);
Cube c = new Cube();
c.SetCube(5);
Box b = new Box();
b.SetBox(10,20,30);
while (true)
{
Console.WriteLine("Enter a choice : ");
Console.WriteLine("1 - Rectangle");
Console.WriteLine("2 - Triangle");
Console.WriteLine("3 - Cube");
Console.WriteLine("4 - Box");
Console.WriteLine("5 - Exit");
choice = Convert.ToInt32(Console.ReadLine());
if (choice == 1)
s = r;
if (choice == 2)
s = t;
if (choice == 3)
s = c;
if (choice == 4)
s = b;
if (choice == 5)
break;
s.Area(); //Call is resolved at run-time
}
}
}
30 | P a g e
Learn C# - do it yourself way... 2008
8.3 Abstract Classes and Abstract
Methods
Abstraction is the ability to make a class/method/property abstract in
C#. An abstract class is the one which cannot be instantiated. All
other functionalities of the class still exist, its fields, its methods and
constructors are all accessed in the same way. You just cannot create
objects of an abstract class.
An abstract class might initially seem like an odd design. Why write a
class and not allow anyone to create objects of it?
The Employee class that we have written in the previous programs is
an example where we do not want to create objects of Employee.
Notice, that the Employee class does not have any information about
salary and how much his pay comes to. It is safe to say, that no
employee of our organisation would like to be strictly an object of
Employee. This means, although we need the Employee class as a
parent of Salary and Hourly to support inheritance, we do not want to
create any objects of this class.
We can make it, so that no one can create objects of Employee class,
by declaring the Employee class abstract. The only result of making
the Employee class abstract is that we can no longer create objects of
Employee.
If the Employee class is made abstract, the following statement will
not compile –
Employee e;
e = new Employee(“George W.”,”Houston”,43); //Error
Just like you can make a class abstract, you can also make a method
abstract. For example, we could have a computePay() method in the
Employee class as abstract.
31 | P a g e
Learn C# - do it yourself way... 2008
An abstract method is never called. Think about it. If computePay() is
abstract in the Employee() class, we really don’t care what
computePay() does in the Employee class, because it will never be
invoked/called. So, the abstract computePay() method in the
Employee class will be empty. Our assumption is that the child
classes of Employee will override the computePay().
This is where abstract methods are useful. If you want a class to
contain a particular method, but you want the actual implementation
to be determined by the child classes, you must declare the method in
the parent class as abstract. Abstract methods consist of a method
signature, but no method body.
public abstract class Employee
{
public string name;
public string address;
public int SSN;
public int number;
public abstract void computePay();
}
8.4 Sealed Keyword
Sealed keyword works exactly opposite to abstract.
- A Sealed class cannot be sub-classed.
- A Sealed method cannot be overridden.
8.5 Namespaces
Every class belongs to a namespace. Namespaces basically have two
purposes –
1. Namespace provides a mechanism for organising classes.
2. Namespace does compartmentalization.
When developing a C# program, you put classes that go together in
the same namespace. For example, in C# the classes that are used to
32 | P a g e
Learn C# - do it yourself way... 2008
perform basic Input and Output are in System namespace. The classes
used for GUI applications are in System.Windows.Forms namespace.
The classes used for creating threads are in System.Threading
namespace.
Q. Why are namespaces necessary? What if I have a small program
that is only a dozen classes?
Namespace is more than just a mechanism for organising classes. A
more important aspect of namespaces is that they create
compartments. For example, suppose that your program contains a
class named Vehicle. What if I wrote a class Vehicle as well? How
would you be able to tell them apart. What if someone wanted to use
my Vehicle class and your Vehicle class in their program?
Q. I have seen this problem before. Why don’t you change the names
of the classes, such as Vehicle1 and Vehicle2?
No thanks. I would have to re-write and re-compile a bunch of code.
With namespaces, I don’t have to worry about it. If the two Vehicle
classes are in different namespace/compartments, my C# program can
distinguish between the two Vehicle classes.
8.6 Adding a class to a Namespace
To add a class to a namespace/compartment, we use the namespace
keyword.
namespace A{
...
}
For example, if you wanted to put Employee, Salary and Hourly
classes in the payroll namespace/compartment we can do it as follows
–
33 | P a g e
Learn C# - do it yourself way... 2008
using System;
namespace payroll
{
public class Employee
{
//Body of the class
}
public class Salary : Employee
{
//Body of the class
}
public class Hourly : Employee
{
//Body of the class
}
}
The Employee, Salary and Hourly classes are now all in the same
namespace.
8.7 Compartments created by
Namespaces
Namespace creates a compartment for all classes. If we put a class
inside a namespace/compartment, the namespace becomes a part of
the name of the class. Say for example, when we put Employee class
inside payroll package, the name of the class now becomes
payroll.Employee
The Employee class can now no longer be accessed by the name
Employee. To refer to the Employee class, we must everytime call it
payroll.Employee. Similarly, we must refer to Salary and Hourly
classes as payroll.Salary and payroll.Hourly.
Suppose you have a written a Vehicle class, and I too have written a
Vehicle class. Kate wants to use both the Vehicle classes in their
program. So, I put my Vehicle class in a compartment quasar, and you
put your vehicle class in another compartment student. Kate will now
refer to both the Vehicle classes as,
34 | P a g e
Learn C# - do it yourself way... 2008
quasar.Vehicle
student.Vehicle
To create objects of these classes, Kate would write
quasar.Vehicle v1 = new quasar.Vehicle();
student.Vehicle v2 = new student.Vehicle();
Here, v1 refers to a quasar.Vehicle object, whereas v2 refers to
student.Vehicle object.
Thus, from the above example, you can deduce the fact that,
namespaces help you to avoid naming conflicts by creating
compartments.
Note – Classes within the same namespace/compartment do not need
to use the <namespace>.<class-name> convention while referring to
each other. Thus, if write another class Test inside payroll namespace,
we can call Employee, Salary and Hourly classes directly without
using any special naming convention. Classes in the same
compartment find each other without any special syntax.
8.8 using Keyword
If a class wants to refer to another class within the same
namespace/compartment, the namespace need not be used. We could
refer to it directly.
However, outside the compartment, we must use the fully qualified
name of the class. Consider the following program :
using System;
namespace payroll
{
public class Employee
{
public string name;
public string address;
public int SSN;
public int number;
35 | P a g e
Learn C# - do it yourself way... 2008
public Employee(string n, string a, int ssn, int num)
{
name = n;
address = a;
SSN = ssn;
number = num;
}
}
}
There is another class Boss which would like create Employee
objects.
using System;
class Boss
{
public static void Main()
{
payroll.Employee e = new payroll.Employee("Jane Smith", "111 Oak
drive", 999001111, 1);
}
}
Writing payroll.Employee everytime could become tedious or
cumbersome. To make things easy, we can use the using keyword.
using keyword specifies in which namespace to look for the given
classes. If you write using payroll, then we can refer to the Employee
class, simply as Employee without using the fully-qualified name.
using System;
using payroll;
class Boss
{
public static void Main()
{
Employee e = new Employee("Jane Smith", "111 Oak street",
999001111, 1);
}
}
Note that, using keyword is just a convenience statement. During
compilation, the C# compiler will replace all instances of Employee
class with payroll.Employee(Fully-Qualified name).
36 | P a g e
Learn C# - do it yourself way...
8.9 Skeleton of a C# Executable
8.10 Interfaces
An interface is a collection of abstract
an interface thereby inheriting the abstract methods of the interface.
All the methods of an interface need to be defined in the class.
Syntactically, an interface is defined using the C# interface keyword.
public interface IName
{
void method1();
void method2();
}
In the .NET Framework, interfaces have a special naming convention.
All interface names begin with a capital I.
Interfaces can have properties as well.
Difference from a class
1. You cannot create an object
File1.cs
namespace A{....}
class A{//Body of class}
Skeleton of a C# Executable
Interfaces
An interface is a collection of abstract members. A class implements
an interface thereby inheriting the abstract methods of the interface.
All the methods of an interface need to be defined in the class.
Syntactically, an interface is defined using the C# interface keyword.
In the .NET Framework, interfaces have a special naming convention.
All interface names begin with a capital I.
Interfaces can have properties as well.
Difference from a class –
1. You cannot create an object of an interface.
AssemblyMyProgram.exe
File1.cs File2.cs
namespace A namespace B{....}
//Body of class
class B{//Body of class}
class C{//Body of class}
namespace C{....}
File3.cs
2008
A class implements
an interface thereby inheriting the abstract methods of the interface.
All the methods of an interface need to be defined in the class.
Syntactically, an interface is defined using the C# interface keyword.
In the .NET Framework, interfaces have a special naming convention.
37 | P a g e
Learn C# - do it yourself way... 2008
2. An interface does not contain any constructor.
3. All methods in an interface are abstract.
4. An interface can inherit multiple interfaces.
An interface is like a contract – a promise that a class will implement
a specific set of functionalities. When a class implements an interface,
it signs a contract, a treaty and promises to provide
implementation/definition of all methods or functions declared in the
interface.
C# code can question an object to determine whether it supports an
interface. Interrogating an object is basically asking the question,”Do
you support this interface?”. If the object answers, “Yes, I do!”, than
you can call the methods defined in the interface on the object.
8.11 Exposing Methods through an
Interface
public class Employee : Payable,EmployeeInfo
{
string name, address;
double weeklyPay;
public Employee(string n, string a)
{
name = n;
address = a;
}
public string GetName()
{
return name;
}
public string GetAddress()
{
return address;
}
public void SetName(string n)
{
name = n;
}
public void SetAddress(string a)
{
address = a;
}
38 | P a g e
Learn C# - do it yourself way... 2008
public double GetWeeklyPay()
{
return weeklyPay;
}
public void computePay(int hoursWorked)
{
weeklyPay = hoursWorked * 6.50;
Console.WriteLine("Weekly Pay for : " + name + " is Rs." +
weeklyPay);
}
public void MailCheck()
{
Console.WriteLine("Mailing check to : " + name + " at " + address);
}
}
An organisation has many employees working in it. The Employee of
an organisation is represented by an Employee class object.
Associated with every Employee is his personal information such as
his name, address. Every employee also has a salary and other pay-
related information. The organisation has two departments – Payroll
and Human Resource.
Different parts in an organisation have different data needs. For
example, the payroll department handles the payroll needs, but it does
not need access to or change the personal information of an employee.
On the same lines, the Human Resource department manages the
general information about Employees, but it does not need access to
the Employee’s pay details. How do we realise these business rules in
C#? The answer lies in the innovative use of Interfaces.
Although we cannot instantiate(create an object) an interface, we can
do the following –
39 | P a g e
Learn C# - do it yourself way... 2008
interface MyInterface
{
void a();
void b();
}
class MyClass : MyInterface
{
void a(){
Console.WriteLine(“Inside A”);
}
void b(){
Console.WriteLine(“Inside B”);
}
void c(){
Console.WriteLine(“Inside C”);
}
}
Declare an interface reference
MyInterface iref;
Assign to it, an object of a class that implements this interface
iref = new MyClass();
Using iref, we can call the methods a() and b(), but we cannot call the
method c(). Thus, we can call only those methods on the object,
which are declared and exposed by the interface.
Thus, by assigning an object to an interface reference, we can restrict
access to the methods that can be called on the object.
In the Employee class example, we could take two different interfaces
payable and EmployeeInfo for the Payroll and HR departments. The
payable interface exposes and provides an interface to only those
40 | P a g e
Learn C# - do it yourself way... 2008
methods that are needed by the payroll department. Through the
EmployeeInfo interface, the HR department can only access those
methods which help it to manage Employee Information like name
and address.
public interface Payable
{
void computePay(int hoursWorked);
void MailCheck();
double GetWeeklyPay();
}
public interface EmployeeInfo
{
string GetName();
void SetName(string name);
string GetAddress();
void SetAddress(string address);
}
To represent the Payroll and Human Resource Departments, we write
the Payroll and HumanResource classes.
public class Payroll
{
public void PayEmployee(Payable p)
{
p.computePay(10);
p.MailCheck();
}
}
public class HumanResource
{
public string GetInfo(EmployeeInfo e)
{
return e.GetName() + " " + e.GetAddress();
}
public void ChangeName(EmployeeInfo e, string n)
{
Console.WriteLine("Changing Name for : " + e.GetName());
e.SetName(n);
Console.WriteLine("New name is : " + e.GetName());
}
public void UpdateAddress(EmployeeInfo e, string a)
{
Console.WriteLine("Changing address for : " + e.GetName());
e.SetAddress(a);
Console.WriteLine("New address is :" + e.GetAddress());
}
}
41 | P a g e
Learn C# - do it yourself way... 2008
Now, we write the Main Program, where we take a fictious
Employee, and the payroll and HR departments.
class EmployeeManagement
{
public static void Main()
{
Employee e = new Employee("George Washington","Mt. Vernon");
Payroll payroll = new Payroll();
HumanResource hr = new HumanResource();
payroll.PayEmployee(e);
hr.GetInfo(e);
hr.ChangeName(e, "Bill Gates");
hr.UpdateAddress(e, "Redmond VA");
}
}
42 | P a g e
Learn C# - do it yourself way... 2008
9
File Reading and Writing – I/O
9.1 Concept of Streams
Many applications which you would write, need to store data and
retrieve data from a file. For example, in an Employee Management
System, you would like the Employee details to be stored
permanently in a file on the disk. You would also want to read
Employee data from the file on disk. You might also need to update
an employee’s information in a file, say for example his salary is
raised, or his marital status changes from single to Married.
Reading or writing data to files is a functionality which you require
often while making your application. Thus, it is important that we
study, how we can read or write to files.
However, an application cannot directly read or write data to a file.
To connect an application to a file, we must use a virtual pipe. Just as
a real pipe carries water, the virtual pipe carries bytes of data to and
fro between the application and the file.
This virtual pipe in C# is called a Stream. If the stream connects to a
file, its called FileStream.
43 | P a g e
Learn C# - do it yourself way...
To create a FileStream in C#,
FileStream class.
FileStream fs = new FileStream(<file
access>,<file-Share>)
The FileStream constructor accepts the FileName as the first
argument. This must be the absolute file path. Next,
must be specified. The file mode tells the C# system, which mode you
would like to operate the file in.
The FileMode enum looks like this
enum FileMode{
CreateNew,
Create,
Open,
OpenOrCreate,
Truncate,
Append
}
To create a FileStream in C#, we must create an object of the
FileStream fs = new FileStream(<file-name>,<file-mode>,<file
The FileStream constructor accepts the FileName as the first
argument. This must be the absolute file path. Next, the file mode
must be specified. The file mode tells the C# system, which mode you
would like to operate the file in.
The FileMode enum looks like this –
2008
we must create an object of the
mode>,<file-
The FileStream constructor accepts the FileName as the first
the file mode
must be specified. The file mode tells the C# system, which mode you