Prof. Yousef B. Mahdy -2014-2015, Assuit University, Egypt Visual programming Using C# Prof. Yousef...
117
f. Yousef B. Mahdy -2014-2015, Assuit University, E f. Yousef B. Mahdy -2014-2015, Assuit University, E Visual programming Using C# Prof. Yousef B. Mahdy Prof. Yousef B. Mahdy Chapter four Classes and Objects
Prof. Yousef B. Mahdy -2014-2015, Assuit University, Egypt Visual programming Using C# Prof. Yousef B. Mahdy Chapter four Classes and Objects
Issues in ATM Network ControlVisual programming Using C#
Prof. Yousef B. Mahdy
Introduction
Object-oriented programming (OOP) is a programming paradigm that
uses objects and their interactions to design applications and
computer programs. There are some basic programming concepts in
OOP:
Abstraction
Polymorphism
Encapsulation
Inheritance
The abstraction is simplifying complex reality by modeling classes
appropriate to the problem. The polymorphism is the process of
using an operator or function in different ways for different data
input. The encapsulation hides the implementation details of a
class from other objects. The inheritance is a way to form new
classes using classes that have already been defined.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Objects
Objects are basic building blocks of a C# OOP program. An object is
a combination of data and methods. The data and the methods are
called members of an object. In an OOP program, we create objects.
These objects communicate together through methods. Each object can
receive messages, send messages and process data.
There are two steps in creating an object. First, we define a
class. A class is a template for an object. It is a blueprint which
describes the state and behavior that the objects of the class all
share. A class can be used to create many objects. Objects created
at runtime from a class are called instances of that particular
class.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Class
A class is a template that defines the form of an object. It
specifies both the data and the code that will operate on that
data.
C# uses a class specification to construct objects. Objects are
instances of a class. Thus, a class is essentially a set of plans
that specify how to build an object. It is important to be clear on
one issue: A class is a logical abstraction.
It is not until an object of that class has been created that a
physical representation of that class exists in memory.
If the class is declared as static , then only one copy exists in
memory and client code can only access it through the class itself,
not an instance variable.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Class Definition
When you define a class, you declare the data that it contains and
the code that operates on it. While very simple classes might
contain only code or only data, most real-world classes contain
both.
In general terms, data is contained in data members defined by the
class, and code is contained in function members. It is important
to state at the outset that C# defines several specific flavors of
data and function members. For example, data members (also called
fields) include instance variables and static variables. Function
members include methods, constructors, destructors, indexers,
events, operators, and properties.
For now, we will limit our discussion of the class to its essential
elements. The other types of members are described in later
chapters.
* - Prof Yousef B. Mahdy- * Visual programming- C#
1
A class definition starts with the keyword class followed by the
class name; and the class body, enclosed by a pair of curly braces.
Following is the general form of a class definition:
* - Prof Yousef B. Mahdy- * Visual programming- C#
2
Please note that:
Access specifiers specify the access rules for the members as well
as the class itself, if not mentioned then the default access
specifier for a class type is internal. Default access for the
members is private.
Data type specifies the type of variable, and return type specifies
the data type of the data, the method returns, if any.
To access the class members, you will use the dot (.)
operator.
The dot operator links the name of an object with the name of a
member.
* - Prof Yousef B. Mahdy- * Visual programming- C#
3
An access specifier which specifies how the member can be accessed.
The access specifier is optional, and if absent, then the member is
private to the class. Members with private access can be used only
by other members of their class. While the members with public
access can be used by all other code—even code defined outside the
class.
The general form for declaring an instance variable is shown here:
access type var-name;
Here, access specifies the access; type specifies the type of
variable; and var-name is the variable’s name. Thus, aside from the
access specifier, you declare an instance variable in the same way
that you declare local variables.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Access modifiers
Access modifiers set the visibility of methods and member
fields.
C# has four access modifiers: public, protected, private and
internal.
The public members can be accessed from anywhere.
The protected members can be accessed only within the class itself
and by inherited and parent classes.
The private members are limited to the containing type, e.g. only
within its class or interface.
The internal members may be accessed from within the same assembly
(exe or DLL).
Access modifiers protect data against accidental modifications.
They make the programs more robust.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Example
1
Objects Are Created
The following line was used to declare an object of type
Building:
Box Box1 = new Box(); // Declare Box1 of type Box
This declaration performs three functions. First, it declares a
variable called Box1 of the class type Box. This variable is not,
itself, an object. Instead, it is simply a variable that can refer
to an object. Second, the declaration creates an actual, physical
copy of the object.
This is done by using the new operator. Finally, it assigns to Box1
a reference to that object. Thus, after the line executes, Box1
refers to an object of type Box.
The new operator dynamically allocates (that is, allocates at
runtime) memory for an object and returns a reference to it.
* - Prof Yousef B. Mahdy- * Visual programming- C#
1
This reference is then stored in a variable. Thus, in C#, all class
objects must be dynamically allocated. The fact that class objects
are accessed through a reference explains why classes are called
reference types.
As you might expect, it is possible to separate the declaration of
Box from the creation of the object to which it will refer, as
shown here:
Box Box1; // declare reference to object
Box1 = new Box(); // allocate a Building object
The first line declares Box1 as a reference to an object of type
Box. Thus, Box1 is a variable that can refer to an object, but it
is not an object, itself. The next line creates a new Box object
and assigns a reference to it to Box1. Now, Box1 is linked with an
object.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Using new with Value Types
At this point, you might be asking why you don’t need to use new
for variables of the value types, such as int or float? In C#, a
variable of a value type contains its own value. Memory to hold
this value is automatically provided when the program is run. Thus,
there is no need to explicitly allocate this memory using new.
Conversely, a reference variable stores a reference to an object.
The memory to hold this object must be allocated dynamically,
during execution.
As a point of interest, it is permitted to use new with the value
types, as shown here:
int i = new int();
Doing so invokes the default constructor for type int, which
initializes i to zero. For example:
// Use new with a value type.
* - Prof Yousef B. Mahdy- * Visual programming- C#
1
Console.WriteLine("The value of i is: " + i);
}
}
The output from this program is
The value of i is: 0
In general, invoking new for a value type invokes the default
constructor for that type. It does not, however, dynamically
allocate memory. Frankly, most programmers do not use new with the
value types.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Garbage Collection and Destructors
As you have seen, objects are dynamically allocated from a pool of
free memory by using the new operator. Of course, memory is not
infinite, and the free memory can be exhausted. Thus, it is
possible for new to fail because there is insufficient free memory
to create the desired object. For this reason, one of the key
components of any dynamic allocation scheme is the recovery of free
memory from unused objects, making that memory available for
subsequent reallocation.
In many programming languages, the release of previously allocated
memory is handled manually. For example, in C++, the delete
operator is used to free memory that was allocated. However, C#
uses a different, more trouble-free approach: garbage
collection.
C#’s garbage collection system reclaims objects
automatically—occurring transparently, behind the scenes, without
any programmer intervention.
* - Prof Yousef B. Mahdy- * Visual programming- C#
1
It works like this: When no references to an object exist, that
object is assumed to be no longer needed, and the memory occupied
by the object is eventually released and collected. This recycled
memory can then be used for a subsequent allocation.
It is possible to define a method that will be called just prior to
an object’s final destruction by the garbage collector. This method
is called a destructor, and it can be used in some highly
specialized situations to ensure that an object terminates cleanly.
For example, you might use a destructor to ensure that a system
resource owned by an object is released.
Destructors have this general form:
~class-name( ) {
The this Keyword
When a method is called, it is automatically passed a reference to
the invoking object (that is, the object on which the method is
called). This reference is called this. Therefore, this refers to
the object on which the method is acting. To understand this, first
consider a program that creates a class called Rect that
encapsulates the width and height of a rectangle and that includes
a method called Area( ) that returns its area.
using System;
class Rect {
Width = w;
Height = h;}
1
Console.WriteLine("Area of r1: " + r1.Area());
Console.WriteLine("Area of r2: " + r2.Area());
2
As you know, within a method, the other members of a class can be
accessed directly, without any object or class qualification. Thus,
inside Area(), the statement
return Width * Height;
means that the copies of Width and Height associated with the
invoking object will be multiplied together and the result
returned. However, the same statement can also be written like
this:
return this.Width * this.Height;
Here, this refers to the object on which Area( ) was called. Thus,
this.Width refers to that object’s copy of Width, and this.Height
refers to that object’s copy of Height. For example, if Area() had
been invoked on an object called x, then this in the preceding
statement would have been referring to x. Writing the statement
without using this is really just shorthand.
Actually, no C# programmer would use this as just shown because
nothing is gained and the standard form is easier. However, this
has some important uses.
* - Prof Yousef B. Mahdy- * Visual programming- C#
3
For example, the C# syntax permits the name of a parameter or a
local variable to be the same as the name of an instance variable
When this happens, the local name hides the instance variable. You
can gain access to the hidden instance variable by referring to it
through this. For example, the following is a syntactically valid
way to write the Rect() constructor:
public Rect(int Width, int Height) {
this.Width = Width;
this.Height = Height;
Function Members
A function member contains executable code that performs work for
the class. The following are examples of function members in
C#:
Methods
Properties
Events
Indexers
Methods
A method is a code block containing a series of statements. Methods
must be declared within a class or a structure. It is a good
programming practice that methods do only one specific task.
Methods bring modularity to programs. Proper use of methods bring
the following advantages:
Reducing duplication of code
Improving clarity of the code
Reuse of code
Access level
1
Access level of methods is controlled with access modifiers. They
set the visibility of methods. They determine who can call the
method.
Methods may return a value to the caller. In case our method
returns a value, we provide its data type. If not, we use the void
keyword to indicate that our method does not return values.
Method parameters are surrounded by parentheses and separated by
commas. Empty parentheses indicate that the method requires no
parameters.
The method block is surrounded with { } characters. The block
contains one or more statements that are executed, when the method
is invoked. It is legal to have an empty method block.
A method signature is a unique identification of a method for the
C# compiler. The signature consists of a method name and the type
and kind (value, reference, or output) of each of its formal
parameters. Method signature does not include the return
type.
Any legal character can be used in the name of a method. By
convention, method names begin with an uppercase letter.
* - Prof Yousef B. Mahdy- * Visual programming- C#
2
As explained, instance variables and methods are two of the primary
constituents of classes. In C#, every function must be associated
with a class. A function defined with a class is known as a method
.
Methods are subroutines that manipulate the data defined by the
class and, in many cases, provide access to that data. Typically,
other parts of your program will interact with a class through its
methods. The general form of a method is shown here:
access ret-type name(parameter-list) {
// body of method
}
Here, access is an access modifier that governs what other parts of
your program can call the method. The ret-type specifies the type
of data returned by the method. This can be any valid type,
including class types that you create.
* - Prof Yousef B. Mahdy- * Visual programming- C#
3
If the method does not return a value, its return type must be
void.
The name of the method is specified by name. This can be any legal
identifier other than those that would cause conflicts within the
current declaration space. The parameter-list is a sequence of type
and identifier pairs separated by commas. Parameters are variables
that receive the value of the arguments passed to the method when
it is called. If the method has no parameters, then the parameter
list will be empty.
There are two forms of return: one for use in void methods (those
that do not return a value) and one for returning values.
In a void method, you can cause the immediate termination of a
method by using this form of return:
return ;
4
When this statement executes, program control returns to the
caller, skipping any remaining code in the method. For example,
consider this method:
public void MyMeth() {
if(i == 5) return; // stop at 5
Console.WriteLine();
}}
Here, the for loop will only run from 0 to 5, because once i equals
5, the method returns. It is permissible to have multiple return
statements in a method. For example,
public void MyMeth() {
5
To review: A void method can return in one of two ways—its closing
curly brace is reached, or a return statement is executed.
Example:
{
}
Although methods with a return type of void are not rare, most
methods will return a value. In fact, the ability to return a value
is one of a method’s most useful features. Methods return a value
to the calling routine using this form of return:
return value;
* - Prof Yousef B. Mahdy- * Visual programming- C#
6
}
It is possible to pass one or more values to a method when the
method is called. A value passed to a method is called an argument.
Inside the method, the variable that receives the argument is
called a formal parameter, or just parameter, for short. Parameters
are declared inside the parentheses that follow the method’s name.
The parameter declaration syntax is the same as that used for
variables. The scope of a parameter is the body of its
method.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Example
public bool IsPrime(int x) {
if(x <= 1) return false;
if((x %i) == 0) return false;
return true;
if(ob.IsPrime(i)) Console.WriteLine(i + " is prime.");
1
else
2 is prime.
3 is prime.
2
A method can have more than one parameter. Simply declare each
parameter, separating one from the next with a comma. For example,
here the ChkNum class is expanded by adding a method called
LeastComFactor(), which returns the smallest factor that its two
arguments have in common. In other words, it returns the smallest
whole number value that can evenly divide both arguments.
using System;
class ChkNum {
public bool IsPrime(int x) {
if(x <= 1) return false;
if((x %i) == 0) return false;
return true;
3
public int LeastComFactor(int a, int b) {
int max;
for(int i=2; i <= max/2; i++)
if(((a%i) == 0) && ((b%i) == 0)) return i;
return 1;
4
5
Notice that when LeastComFactor( ) is called, the arguments are
also separated by commas. The output from the program is shown
here:
2 is prime.
3 is prime.
* - Prof Yousef B. Mahdy- * Visual programming- C#
How Arguments Are Passed
let’s review the two ways in which an argument can be passed to a
subroutine.
The first way is call-by-value. This method copies the value of an
argument into the formal parameter of the subroutine. Therefore,
changes made to the parameter of the subroutine have no effect on
the argument used in the call.
By default, C# uses call-by-value, which means that a copy of the
argument is made and given to the receiving parameter. Thus, when
you pass a value type, such as int or double, what occurs to the
parameter that receives the argument has no effect outside the
method.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Example
i = i + j;
Console.WriteLine("a and b before call: " +a+ " " + b);
ob.NoChange(a, b);
}
}
a and b before call: 15 20
a and b after call: 15 20
* - Prof Yousef B. Mahdy- * Visual programming- C#
1
The second way an argument can be passed is call-by-reference. In
this method, a reference to an argument (not the value of the
argument) is passed to the parameter. Inside the subroutine, this
reference is used to access the actual argument specified in the
call. This means that changes made to the parameter will affect the
argument used to call the subroutine.
When you pass a reference to a method, the reference, itself, is
still passed by value. Thus, a copy of the reference is made and
changes to the parameter will not affect the argument. However— and
this is a big however—changes made to the object being referred to
by the parameter will affect the object referred to by the
argument. Let’s see why.
Recall that when you create a variable of a class type, you are
only creating a reference to an object. Thus, when you pass this
reference to a method, the parameter that receives it will refer to
the same object as that referred to by the argument. Therefore, the
argument and the parameter will both refer to the same
object.
* - Prof Yousef B. Mahdy- * Visual programming- C#
2
This means that objects are passed to methods by what is
effectively call-by-reference. Thus, changes to the object inside
the method do affect the object used as an argument. For example,
consider the following program:
using System;
class Test {
a = i;
b = j;
3
Console.WriteLine("ob.a and ob.b before call: " + ob.a + " " +
ob.b);
ob.Change(ob);
}
}
ob.a and ob.b before call: 15 20
ob.a and ob.b after call: 35 -20
* - Prof Yousef B. Mahdy- * Visual programming- C#
4
As you can see, in this case, the actions inside Change( ) have
affected the object used as an argument.
To review: When a reference is passed to a method, the reference
itself is passed by use of call-by-value. Thus, a copy of that
reference is made. However, the copy of that reference will still
refer to the same object as its corresponding argument. This means
that objects are implicitly passed using call-by-reference.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Use ref and out Parameters
C# supports two ways of passing arguments to methods: by value and
by reference. The default passing of arguments is by value. When we
pass arguments by value, the method works only with the copies of
the values. This may lead to performance overheads when we work
with large amounts of data.
You can, however, alter this behavior. Through the use of the ref
and out keywords, it is possible to pass any of the value types by
reference. Doing so allows a method to alter the argument used in
the call.
Before going into the mechanics of using ref and out, it is useful
to understand why you might want to pass a value type by reference.
In general, there are two reasons: to allow a method to alter the
contents of its arguments or to allow a method to return more than
one value.
* - Prof Yousef B. Mahdy- * Visual programming- C#
1
As you know, a return statement enables a method to return a value
to its caller. However, a method can return only one value each
time it is called. What if you need to return two or more pieces of
information?
For example, what if you want to create a method that decomposes a
floating-point number into its integer and fractional parts? To do
this requires that two pieces of information be returned: the
integer portion and the fractional component. This method cannot be
written using only a single return value. The out modifier solves
this problem.
Often you will want a method to be able to operate on the actual
arguments that are passed to it. The quintessential example of this
is a Swap() method that exchanges the values of its two
arguments.
* - Prof Yousef B. Mahdy- * Visual programming- C#
2
Since value types are passed by value, it is not possible to write
a method that swaps the value of two ints, for example, using C#’s
default call-by-value parameter passing mechanism. The ref modifier
solves this problem.
Which way of passing arguments should we use? It depends on the
situation. Say we have a set of data, for example salaries of
employees. If we want to compute some statistics of the data, we do
not need to modify them. We can pass by values. If we work with
large amounts of data and the speed of computation is critical, we
pass by reference. If we want to modify the data, e.g. do some
reductions or raises to the salaries, we might pass by
reference.
* - Prof Yousef B. Mahdy- * Visual programming- C#
3
i = i * i;
Console.WriteLine("a after call: " + a);
a before call: 10
a after call : 100
4
Using ref, it is now possible to write a method that exchanges the
values of its two value-type arguments.
Here is one important point to understand about ref: An argument
passed by ref must be assigned a value prior to the call. The
reason is that the method that receives such an argument assumes
that the parameter refers to a valid value. Thus, using ref, you
cannot use a method to give an argument an initial value.
If your intention is to use the variables solely to obtain some
return values from the method, you can use the out keyword, which
is identical to the ref keyword except that it does not require the
variables passed in to be initialized first.
* - Prof Yousef B. Mahdy- * Visual programming- C#
5
/* Decompose a floating-point value into its integer and fractional
parts. */
public int GetParts(double n, out double frac) {
int whole;
return whole; // return integer portion
}
}
6
Integer portion is 10
Fractional part is 0.125
The GetParts() method returns two pieces of information. First, the
integer portion of n is returned as GetParts( )’s return value.
Second, the fractional portion of n is passed back to the caller
through the out parameter frac. As this example shows, by using
out, it is possible for one method to return two values.
* - Prof Yousef B. Mahdy- * Visual programming- C#
7
The out keyword is similar to the ref keyword. The difference is
that when using the ref keyword, the variable must be initialized
before it is being passed. With the out keyword, it may not be
initialized. Both the method definition and the method call must
use the out keyword.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Use ref and out on References
The use of ref and out is not limited to the passing of value
types. They can also be used when a reference is passed. When ref
or out modifies a reference, it causes the reference, itself, to be
passed by reference. This allows a method to change what object the
reference refers to. Consider the following program, which uses ref
reference parameters to exchange the objects to which two
references are referring:
// Swap two references.
a = i;
b = j; }
* - Prof Yousef B. Mahdy- * Visual programming- C#
1
public void Swap(ref RefSwap ob1, ref RefSwap ob2) {
RefSwap t;
t = ob1;
ob1 = ob2;
ob2 = t;
Console.Write("x before call: ");
2
y.Show();
Console.WriteLine();
x before call: a: 1, b: 2
y before call: a: 3, b: 4
x after call: a: 3, b: 4
y after call: a: 1, b: 2
* - Prof Yousef B. Mahdy- * Visual programming- C#
Use a Variable Number of Arguments
Sometimes you will want to create a method that can be passed an
arbitrary number of arguments. For example, consider a method that
finds the smallest of a set of values. Such a method might be
passed as few as two values, or three, or four, and so on. In all
cases, you want that method to return the smallest value. Such a
method cannot be created using normal parameters. Instead, you must
use a special type of parameter that stands for an arbitrary number
of parameters. This is done by creating a params parameter.
A method can take variable number of arguments. For this we use the
params keyword. No additional parameters are permitted after the
params keyword. Only one params keyword is permitted in a method
declaration.
The params modifier is used to declare an array parameter that will
be able to receive zero or more arguments. The number of elements
in the array will be equal to the number of arguments passed to the
method. Your program then accesses the array to obtain the
arguments.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Example
}
int sum = 0;
sum = sum + i;
}
}
1
We create a Sum() method which can take variable number of
arguments. The method will calculate the sum of values passed to
the method:
Sum(1, 2, 3);
Sum(1, 2, 3, 4, 5);
We call the Sum() method twice. In one case, it takes 3 arguments,
in the second case 5. We call the same method. The Sum() method can
take variable number of integer values. All values are added to the
list array. We compute the sum of the values in the list.
Output:
Example
int m;
if(nums.Length == 0) {
return m;
1
2
Minimum is 10
Minimum is -1
Minimum is 3
Minimum is 8
Return Objects
A method can return any type of data, including class types. For
example, the following
version of the Rect class includes a method called Enlarge( ) that
creates a rectangle that
is proportionally the same as the invoking rectangle, but larger by
a specified factor:
// Return an object.
width = w; height = h;
1
}}
Console.Write("Dimensions of r1: "); r1.Show();
Console.WriteLine("Area of r1: " + r1.Area());
2
Area of r1: 20
Area of r2: 80
3
When an object is returned by a method, it remains in existence
until there are no more references to it. At that point, it is
subject to garbage collection. Thus, an object won’t be destroyed
just because the method that created it terminates.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Return an Array
Since in C# arrays are implemented as objects, a method can also
return an array. (This differs from C++ in which arrays are not
valid as return types.) For example, in the following program, the
method FindFactors( ) returns an array that holds the factors of
the argument that it is passed:
using System;
class Factor {
int[] facts = new int[80]; // size of 80 is arbitrary
int i, j;
if( (num%i)==0 ) {
1
Console.Write(factors[i] + " ");
Factors for 1000 are:
2 4 5 8 10 20 25 40 50 100 125 200 250 500
* - Prof Yousef B. Mahdy- * Visual programming- C#
Avoiding Unreachable Code
When creating methods, you should avoid causing a situation in
which a portion of code cannot, under any circumstances, be
executed. This is called unreachable code, and it is considered
incorrect in C#. The compiler will issue a warning message if you
create a method that contains unreachable code. For example:
public void MyMeth() {
char a, b;
1
Here, the method MyMeth( ) will always return before the final
WriteLine( ) statement is executed. If you try to compile this
method, you will receive a warning. In general, unreachable code
constitutes a mistake on your part, so it is a good idea to take
unreachable code warnings seriously.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Understanding static
There will be times when you will want to define a class member
that will be used independently of any object of that class.
Normally, a class member must be accessed through an object of its
class, but it is possible to create a member that can be used by
itself, without reference to a specific instance. To create such a
member, precede its declaration with the keyword static. When a
member is declared static, it can be accessed before any objects of
its class are created and without reference to any object. You can
declare both methods and variables to be static. The most common
example of a static member is Main( ), which is declared static
because it must be called by the operating system when your program
begins.
Outside the class, to use a static member, you must specify the
name of its class followed by the dot operator. No object needs to
be created. In fact, a static member cannot be accessed through an
object reference.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Static Members
Static data members belong to the class rather than to each
instance of the class. You use the static keyword to define them.
For example, here the Contact class has a static member named count
:
public class Contact {
}
The count static member can be used to keep track of the total
number of Contact instances, and thus it should not belong to any
instances of the Contact class but to the class itself.
* - Prof Yousef B. Mahdy- * Visual programming- C#
1
To use the count static variable, access it through the Contact
class:
Contact.count = 4;
Console.WriteLine(Contact.count);
Constants defined within a class are implicitly static, as the
following example shows:
public class Contact
public static int count;
Method overloading
Method overloading allows the creation of several methods with the
same name which differ from each other in the type of the
input.
The key is, while two methods can have the same name, they can't
have the same "signature". A method's signature is defined as the
combination of the method name and the types and order of the
parameters that get passed in. Note that this does not include the
parameters' names, just their types. (This is because when you call
a method, the C# compiler can figure out which of the different
"overloads" is supposed to be used based on the method name and the
kinds of data that are being passed in, though the actual names of
the variables don't matter when you're calling a method, so they
are ignored.)
* - Prof Yousef B. Mahdy- * Visual programming- C#
1
As an example, to help illustrate what a method signature is, take
the following example:
static int Multiply(int a, int b){
return a * b;
}
This has a signature that looks like this: static int Multiply(int,
int). You can only overload a method if you use a different
signature. So for instance, the following code snippet works:
static int Multiply(int a, int b){
return a * b;
return a * b * c;
2
This works, because the two multiply methods have a different
number of parameters, and so as a result, a different signature. We
could also define a Multiply method that has no parameters (just
int Multiply()) or one parameter (int Multiply(int)) though,
admittedly, in this particular case, I can't imagine how either of
those two methods would do multiplication with zero or one things.
(Hey, it's just an example!).
Also, you can have the same number of parameters, if their types
are different:
static int Multiply(int a, int b){
return a * b;
return a * b;
2
return x + y; }
3
The magic of method overloading is that you can have many methods
that do very similar work on different types of data (like the int
multiplication and the double multiplication above) without having
to have a completely different method name. It makes things easier
on the people calling the method (yourself, for starters, but the
other people on your team as well). With different signatures, the
C# compiler can determine which of the overloaded methods to
use.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Recursion
Recursion, in mathematics and computer science, is a way of
defining methods in which the method being defined is applied
within its own definition. In other words, a recursive method calls
itself to do its job.
The recursion , it is where you call a method from inside itself.
Here's a trivial example (which happens to break on you when you
run it):
static void MethodThatUsesRecursion()
}
Like I said (repeatedly), this example is going to break on you,
because it just keeps going into deeper and deeper methods.
* - Prof Yousef B. Mahdy- * Visual programming- C#
1
The problem with this first example, is that there is no "base
case". It will never get to a point where it is done, and can start
returning from the method calls, back up to the starting
point.
A base case is a situation where there is no need to keep going
further, and the method can simply return without "recursing"
further.
Perhaps you remember from math classes that the factorial, written
as an exclamation mark by a number (like "7!") means 7 * 6 * 5 * 4
* 3 * 2 * 1. 72! Would be 72 * 71 * 70 * 69 * … * 3 * 2 * 1.
In this case, we know that 1! is 1. This can function as a base
case. Every other number, say 7!, can be thought of as the number
multiplied by the factorial of the number one less than it (7 *
6!).
* - Prof Yousef B. Mahdy- * Visual programming- C#
Example
Example-The Fibonacci Numbers
The Fibonacci numbers are the numbers in the following sequence:
0,1,1,2,3,5,8,13,21,34,55,…
If F0 = 0 and F1= 1 then:
Fn = Fn-1 + Fn-2
The following code is a method to compute Fn (no recursive and high
performance):
public long Fib(int n){
f[0] = 0;
f[1] = 1;
f[i] = f[i - 1] + f[i - 2];
return f[n];
1
If we use recursive method, our code will be more simple, but a
very poor performance:
public long Fib(int n)
return n;
}
Method scope
A variable declared inside a method has a method scope. The scope
of a name is the region of program text within which it is possible
to refer to the entity declared by the name without the
qualification of the name. A variable which is declared inside a
method has a method scope. It is also called a local scope. The
variable is valid only in this particular method.
The Main() method is an entry point to the C# console and GUI
application. In C#, the Main() method is required to be static.
Before the application starts, no object is created yet. To invoke
non-static methods, we need to have an object instance. Static
methods exist before a class is instantiated so static is applied
to the main entry point.
* - Prof Yousef B. Mahdy- * Visual programming- C#
1
}}
}
}
In our code example, we define a static ShowInfo() method. A static
method can only work with static variables. To invoke a static
method, we do not need an object instance. We call the method by
using the name of the class and the dot operator.
* - Prof Yousef B. Mahdy- * Visual programming- C#
The constructor
A constructor is a special kind of a method. It is automatically
called when the object is created. Constructors do not return
values. The purpose of the constructor is to initiate the state of
an object. Constructors have the same name as the class. The
constructors are methods, so they can be overloaded too.
Also, usually, access is public because constructors are normally
called from outside their class.
Constructors cannot be inherited. They are called in the order of
inheritance. If we do not write any constructor for a class, C#
provides an implicit default constructor. If we provide any kind of
a constructor, then a default is not supplied.
* - Prof Yousef B. Mahdy- * Visual programming- C#
1
}
}
}
We have a Being class. This class has two constructors. The first
one does not take parameters; the second one takes one
parameter.
* - Prof Yousef B. Mahdy- * Visual programming- C#
2
This constructor takes one string parameter.
new Being();
An instance of the Being class is created. This time the
constructor without a parameter is called upon object
creation.
Output:
Being Tom is created
In the next example, we initiate data members of the class.
Initiation of variables is a typical job for constructors.
* - Prof Yousef B. Mahdy- * Visual programming- C#
3
this.name = name;
this.born = born;
this.name, this.born.ToShortDateString());
4
MyFriend fr = new MyFriend(name, born);
fr.Info();
}
}
In the constructor, we initiate the two data members. The this
variable is a handler used to reference the object variables.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Constructor chaining
Constructor chaining is the ability of a class to call another
constructor from a constructor. To call another constructor from
the same class, we use the this keyword.
using System;
}
1
}
}
We have a Circle class. The class has two constructors. One that
takes one parameter and one that does not take any
parameters.
public Circle(int radius){
This constructor takes one parameter — the radius.
public Circle() : this(1) {}
This is the constructor without a parameter. It simply calls the
other constructor and gives it a default radius of 1.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Class constants
C# enables to create class constants. These constants do not belong
to a concrete object. They belong to the class. By convention,
constants are written in uppercase letters.
using System;
}
}
The const keyword is used to define a constant. The public keyword
makes it accessible outside the body of the class.
* - Prof Yousef B. Mahdy- * Visual programming- C#
The ToString() method
Each object has a ToString() method. It returns a human-readable
representation of an object. The default implementation returns the
fully qualified name of the type of the Object. Note that when we
call the Console.WriteLine() method with an object as a parameter,
the ToString() is being called.
using System;
public class ToStringMethod{
static void Main() {
Console.WriteLine(o.ToString());
Console.WriteLine(b.ToString());
Console.WriteLine(b); }
1
Each class created inherits from the base object. The ToString()
method belongs to this object class. So, We have a Being class in
which we override the default implementation of the ToString()
method. We use the override keyword to inform that we are
overriding a method.
Output:
System.Object
Properties
A field is a variable that is declared directly in a class or
struct. A class or struct may have instance fields or static fields
or both. Generally, you should use fields only for variables that
have private or protected accessibility. Data that your class
exposes to client code should be provided through methods,
properties and indexers. By using these constructs for indirect
access to internal fields, you can guard against invalid input
values.
A property is a member that provides a flexible mechanism to read,
write, or compute the value of a private field. Properties can be
used as if they are public data members, but they are actually
special methods called accessors. This enables data to be accessed
easily and still helps promote the safety and flexibility of
methods.
* - Prof Yousef B. Mahdy- * Visual programming- C#
1
Properties enable a class to expose a public way of getting and
setting values, while hiding implementation or verification code. A
get property accessor is used to return the property value, and a
set accessor is used to assign a new value.
Property reads and writes are translated to get and set method
calls. Accessing variables with a field notation (e.g. object.Name)
is easier than with custom method calls (e.g. object.GetName()).
However with properties, we still have the advantage of
encapsulation and information hiding. In other words, properties
shield the data from the outside world while having a convenient
field access.
A property is much like a combination of a variable and a method -
it can't take any parameters, but you are able to process the value
before it's assigned to our returned.
* - Prof Yousef B. Mahdy- * Visual programming- C#
2
A property consists of 2 parts, a get and a set method, wrapped
inside the property:
private string color;
public string Color
}
The get method should return the variable, while the set method
should assign a value to it. Our example is as simple as it gets,
but it can be extended. Another thing you should know about
properties is the fact that only one method is required - either
get or set, the other is optional. This allows you to define
read-only and write-only properties.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Example
1
We have a simple Person class with one property. We have a property
that is called Name. It looks like a regular method declaration.
The difference is that it has specific accessors called get and
set.
A get property accessor is used to return the property value, and a
set accessor is used to assign a new value. The value keyword is
used to define the value being assigned by the set indexer.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Read-only properties
It is possible to create read-only properties. To create a
read-only property, we omit the set accessor and provide only the
get accessor in the implementation.
using System;
Creating a Write-Only Property
You can assign values to, but not read from, a write-only property.
A write-only property only has a set accessor.
using System;
1
}}
This time, the get accessor is removed from the ID and Name
properties of the Customer class. The set accessors have been
added, assigning value to the backing store fields, m_id and
m_name.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Automatic properties
The patterns you see here, where a property encapsulates a property
with get and set accessors, without any other logic is common. It
is more code than we should have to write for such a common
scenario. That's why C# 3.0 introduced a new syntax for a property,
called an auto-implemented property, which allows you to create
properties without get and set accessor implementations.
We can mark properties with access modifiers like public, private
or protected. Properties can be also static, abstract, virtual and
sealed. Their usage is identical to regular methods.
* - Prof Yousef B. Mahdy- * Visual programming- C#
1
}
Console.ReadKey();
Object Initializers
With C# 3.0, initializing both objects and collections have become
much easier. Consider this simple Car class, where we use the
automatic properties described before:
class Car{
publi c Color Color { get; set; }
}
Now, in C# 2.0, we would have to write a piece of code like this to
create a Car instance and set its properties:
Car car = new Car();
car.Color = Color.Yellow;
It's just fine really, but with C# 3.0, it can be done a bit more
cleanly, thanks to the new object initializer syntax:
* - Prof Yousef B. Mahdy- * Visual programming- C#
1
Car car = new Car { Name = "Chevrolet Corvette", Color =
Color.Yellow };
As you can see, we use a set of curly brackets after instantiating
a new Car object, and within them, we have access to all the public
properties of the Car class. This saves a bit of typing, and a bit
of space as well. The cool part is that it can be nested too.
Consider the following example, where we add a new complex property
to the Car class, like this:
class Car{
}
2
}
To initialize a new car with C# 2.0, we would have to do something
like this:
Car car = new Car();
3
With C# 3.0, we can do it like this instead:
Car car = new Car {
Extension Methods
Extension methods enable you to add methods to existing types
without creating a new derived type, recompiling, or otherwise
modifying the original type. An extension method is a special kind
of static method, but they are called as if they were instance
methods on the extended type.
An extension method is a static method of a static class, where the
"this" modifier is applied to the first parameter. The type of the
first parameter will be the type that is extended.
Extension methods are only in scope when you explicitly import the
namespace into your source code with a using directive.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Benefits of extension methods
Extension methods allow existing classes to be extended without
relying on inheritance or having to change the class's source
code.
If the class is sealed than there in no concept of extending its
functionality. For this a new concept is introduced, in other words
extension methods.
This feature is important for all developers, especially if you
would like to use the dynamism of the C# enhancements in your
class's design.
An extension method is a special kind of static method that allows
you to add new methods to existing types without creating derived
types.
The extension methods are called as if they were instance methods
from the extended type, For example: x is an object from int class
and we called it as an instance method in int class.
* - Prof Yousef B. Mahdy- * Visual programming- C#
1
Suppose that you want to extend int class in .NET by adding a
factorial method to it using recursion technique.
One way of thinking is to inherit int class and add your new method
to it and use your new methods in your code. This is a valid
solution but let us see what extension methods can provide
us.
Using extension methods, you can use your new methods as a part of
int class in .NET.
How to Create my Extension Method?
Simply, you create your own static method in your class and put
this keyword in front of the first parameter in this method
(the type that will be extended).
* - Prof Yousef B. Mahdy- * Visual programming- C#
Example
if (x <= 1) return 1;
if (x == 2) return 2;
else
tips
This keyword has to be the first parameter in the extension method
parameter list.
It is important to note that extension methods can't access the
private methods in the extended type.
If you want to add new methods to a type, you don't have the source
code for it, the ideal solution is to use and implement extension
methods of that type.
If you create extension methods that have the same signature
methods inside the type you are extending, then the extension
methods will never be called.
* - Prof Yousef B. Mahdy- * Visual programming- C#
Example
if(str.Length < 3){
return str;
str = str.GetFirstThreeCharacters();