Details on the Methods of a Class

 Methods and Local Variables

 Introduction

In the body of a method, you can declare one or more variables that would be used only by the method. A variable declared in the body of a method is referred to as a local variable. The variable cannot be accessed outside of the method it belongs to. After declaring a local variable, it is made available to the method and you can use it as you see fit, for example, you can assign it a value prior to using it.

 Practical Learning: Using a Method's Local Variables
1. Start Microsoft Visual C# and create a Console Application named Geometry1
2. To create a new class, on the main menu, click Project -> Add Class...
3. Set the Name to Cylinder and click Add
4. To declare and use local variables of a method, change the file as follows:

5. Access the Program.cs file and change it as follows:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Geometry1 { public class Program { static void Main() { Cylinder cyl = new Cylinder(); cyl.Process(); Console.WriteLine(); } } }
6. Execute the application to test it. Here is an example:

 Enter the dimensions of the cylinder Radius: 38.64 Height: 22.48 Cylinder Characteristics Radius: 38.64 Height: 22.48 Base: 4690.55 Lateral: 5457.75 Total: 14838.85 Volume: 105443.65
7. Close the DOS window
 A Method that Returns a Value

If a method has carried an assignment and must make its result available to other methods or other classes, the method must return a value and cannot be void. To declare a method that returns a value, provide its return type to the left of its name. Here is an example:

using System;

class Exercise
{
double Operation()
{
}

static void Main()
{
}
}

After a method has performed its assignment, it must clearly demonstrate that it is returning a value. To do this, you use the return keyword followed by the value that the method is returning. The value returned must be of the same type specified as the return type of the method. Here is an example:

using System;

class Exercise
{
double Operation()
{
return 24.55;
}

static void Main()
{
}
}

A method can also return an expression, provided the expression produces a value that is conform to the return type. Here is an example:

using System;

class Exercise
{
double Operation()
{
return 24.55 * 4.16;
}

static void Main()
{
}
}

When a method returns a value, the compiler considers such a method as if it were a regular value. This means that you can use the Console.Write() or the Console.WriteLine() method to display its value. To do this, simply type the name of the method and its parentheses in the Console.Write() of the Console.WriteLine() methods' parentheses.

Remember that in the main class of an application, that is, in the class that contains the Main() method, Main() is created as static. Therefore, if you want to access a method other than Main in Main, you can create the method as static and then access it directly in Main. Here is an example:

using System;

class Exercise
{
static double Operation()
{
return 24.55;
}

static void Main()
{
Console.WriteLine(Operation());
}
}

Otherwise, if the method is not created as static, you must declare an instance of the class in Main and use that instance to access the method using the period operator. Here is an example:

using System;

class Exercise
{
double Operation()
{
return 24.55;
}

static void Main()
{
Exercise exo = new Exercise();

Console.WriteLine(exo.Operation());
}
}

Of course you can use the var keyword to declare an instance of the class.

We have seen how to call a method from the parentheses of another method that needs its result. In the same way, a method that returns a value can be assigned to a variable of the same type.

 Practical Learning: Returning a Value From a Method
1. Access the Cylinder.cs file
2. To create methods that return values, change the file as follows:

3. Execute the application. Here is an example:

 Enter the dimensions of the cylinder Radius: 52.08 Height: 36.44 Cylinder Characteristics Radius: 52.08 Height: 36.44 Base: 8521.02 Lateral: 11924.20 Total: 28966.25 Volume: 310506.14
4. Close the DOS window
 The Main Method of an Application

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

using System;

class Exercise
{
static char HaveCharacter()
{
return 'G';
}

static int Main()
{
Console.Write("Character: ");
Console.WriteLine(HaveCharacter());

return 244006;
}
}

This would produce:

Character: G
Press any key to continue . . .
 Methods' Arguments

 Introduction

A method performs an assignment that completes the operations of a class. The methods we used in the previous sections relied on local variables to exchange information with other sections of the program. Sometimes, a method would need one or more values in order to carry its assignment. The particularity of such a value or such values is that another method that calls this one must supply the needed value(s). When a method needs a value to complete its assignment, such a value is called an argument.

Like a variable, an argument is represented by its type of value. For example, one method may need a character while another would need a string. Yet another method may require a decimal number. This means that the method or class that calls a method is responsible for supplying the right value, even though a method may have an internal mechanism of checking the validity of such a value.

The value supplied to a method is typed in the parentheses of the method and it's called an argument. In order to declare a method that takes an argument, you must specify its name and the argument between its parentheses. Because a method must specify the type of value it would need, the argument is represented by its data type and a name.

Suppose you want to define a method that displays the side length of a square. Since you would have to supply the length, you can define such a method as follows:

using System;

public class Exercise
{
static void DisplaySide(double Length)
{
}

static int Main()
{
return 0;
}
}

In the body of the method, you may or may not use the value of the argument. Otherwise, you can manipulate the supplied value as you see fit. In this example, you can display the value of the argument as follows:

using System;

public class Exercise
{
static void DisplaySide(double Length)
{
Console.Write("Length: ");
Console.WriteLine(Length);
}

static int Main()
{
return 0;
}
}

When calling a method that takes an argument, you must supply a value for the argument; otherwise you would receive an error. Also, you should/must supply the right value; otherwise, the method may not work as expected and it may produce an unreliable result. Here is an example:

using System;

public class Exercise
{
static void DisplaySide(double Length)
{
Console.Write("Length: ");
Console.WriteLine(Length);
}

static int Main()
{
DisplaySide(35.55);

return 0;
}
}

As mentioned already, a method that takes an argument can also declare its own local variable(s). A method can take more than one argument. When defining such a method, provide each argument with its data type and a name. The arguments are separated by a comma.

 Practical Learning: Passing Arguments
1. Access the Cylinder.cs file and change it as follows:

2. Execute the program:

 Enter the dimensions of the cylinder Radius: 35.96 Height: 30.28 Cylinder Characteristics Radius: 35.96 Height: 30.28 Base: 4062.46 Lateral: 6841.56 Total: 14966.49 Volume: 123011.33
3. Close the DOS window
 Techniques of Passing Arguments

 Passing an Argument by Value

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

 Passing an Argument by Reference

Consider the following program:

using System;

public class Payroll
{
static void Earnings(double ThisWeek, double Salary)
{
ThisWeek = 42.50;

Console.WriteLine("\nIn the Earnings() function,");
Console.Write("Weekly Hours    = ");
Console.WriteLine(ThisWeek);
Console.Write("Salary          = ");
Console.WriteLine(Salary);
Console.Write("Weekly Salary:  = ");
Console.WriteLine(ThisWeek * Salary);
}

static int Main()
{
double Hours, Rate;

Rate = 15.58;
Hours = 26.00;

Console.WriteLine("In the Main() method,");
Console.Write("\nWeekly Hours   = ");
Console.Write(Hours);
Console.Write("\nSalary         = ");
Console.WriteLine(Rate);
Console.Write("Weekly Salary    = ");
Console.WriteLine(Hours * Rate);

Console.WriteLine("\nCalling the Earnings() method");

Earnings(Hours, Rate);

Console.Write("\nAfter calling the Earnings() method, ");
Console.WriteLine("\nin the Main() function,");
Console.Write("\nWeekly Hours   = ");
Console.Write(Hours);
Console.Write("\nSalary         = ");
Console.WriteLine(Rate);
Console.Write("Weekly Salary    = ");
Console.WriteLine(Hours * Rate);

Console.Write("\n");
return 0;
}
}

This would produce:

In the Main() method,

Weekly Hours   = 26
Salary         = 15.58
Weekly Salary  = 405.08

Calling the Earnings() method

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

After calling the Earnings() method,
in the Main() function,

Weekly Hours   = 26
Salary         = 15.58
Weekly Salary  = 405.08

Press any key to continue

Notice that the weekly hours and salary values are the same before and after calling the Earnings() method.

When you declare a variable in a program, the compiler reserves an amount of space for that variable. If you need to use that variable somewhere in your program, you call it and make use of its value. There are two major issues related to a variable: its value and its location in the memory. The location of a variable in memory is referred to as its address.

If you supply the argument using its name, the compiler only makes a copy of the argument’s value and gives it to the calling method. Although the calling method receives the argument’s value and can use it in any way, it cannot (permanently) alter it. C# allows a calling method to modify the value of a passed argument if you find it necessary. If you want the calling method to modify the value of a supplied argument and return the modified value, you should pass the argument using its reference.

To pass an argument as a reference, when defining and when calling the method, precede the argument's data type with the ref keyword. You can pass 0, one, or more arguments as reference in the program or pass all arguments as reference. The decision as to which argument(s) should be passed by value or by reference is based on whether or not you want the called method to modify the argument and permanently change its value.

Another option consists of passing an argument using the out keyword. Here is an example:

using System;

class Exercise
{
static void Initializer(out double n)
{
n = 128.44;
}

public static int Main()
{
double Number = 15.25;

Console.WriteLine("Number = {0}", Number);
return 0;
}
}

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

using System;

class Exercise
{
static void Initializer(out double n)
{
n = 128.44;
}

public static int Main()
{
double Number = 15.25;

Console.WriteLine("Number = {0}", Number);
Initializer(out Number);
Console.WriteLine("Number = {0}", Number);
return 0;
}
}

This would produce:

Number = 15.25
Number = 128.44
 Practical Learning: Passing Arguments By Reference
1. To pass arguments by reference, change the Cylinder.cs file as follows:

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

 Enter the dimensions of the cylinder Radius: 24.55 Height: 20.85 Cylinder Characteristics Radius: 24.55 Height: 20.85 Base: 1893.45 Lateral: 3216.16 Total: 7003.05 Volume: 39478.34
3. Close the DOS window

A typical program involves a great deal of names that represent variables and methods of various kinds. The compiler does not allow two variables to have the same name in the same method. Although two methods should have unique names in the same program, a class can have different methods with the same name if you follow some rules. The ability to have various methods with the same name in the same program is referred to as method overloading. To perform overloading, the methods must have different numbers or different type(s) of arguments.

The moment of inertia is the ability of a beam to resist bending. It is calculated with regard to the cross section of the beam. Because it depends on the type of section of the beam, its calculation also depends on the type of section of the beam. In this exercise, we will review different formulas used to calculate the moment of inertia. Since this exercise is for demonstration purposes, you do not need to be a Science Engineering major to understand it.

1. Create a new Console Application named MomentOfInertia1

2. Change the file as follows:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; public class Exercise { // Rectangle static double MomentOfInertia(double b, double h) { return b * h * h * h / 3; } static int Main() { double Base, Height; Console.WriteLine("Enter the dimensions of the Rectangle"); Console.Write("Base: "); Base = double.Parse(Console.ReadLine()); Console.Write("Height: "); Height = double.Parse(Console.ReadLine()); Console.WriteLine("\nMoment of inertia with " + "regard to the X axis: "); Console.WriteLine("I = {0}mm", MomentOfInertia(Base, Height)); Console.WriteLine(); return 0; } }
3. Execute the application. Here is an example of running the program:

 Enter the dimensions of the Rectangle Base: 2.44 Height: 3.58 Moment of inertia with regard to the X axis: I = 37.3179390933333mm
4. Close the DOS window
5. A circle, and thus a semi-circle, requires only a radius. Since the other version of the MomentOfInertia() function requires two arguments, we can overload it by providing only one argument, the radius.
To overload the above MomentOfInertia() method, type the following in the file:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; public class Exercise { // Rectangle static double MomentOfInertia(double b, double h) { return b * h * h * h / 3; } // Semi-Circle static double MomentOfInertia(double R) { const double PI = 3.14159; return R * R * R * R * PI/ 8; } static int Main() { double Base, Height; double Radius; Console.WriteLine("Enter the dimensions of the Rectangle"); Console.Write("Base: "); Base = double.Parse(Console.ReadLine()); Console.Write("Height: "); Height = double.Parse(Console.ReadLine()); Console.WriteLine("\nMoment of inertia with regard to the X axis: "); Console.WriteLine("I = {0}mm", MomentOfInertia(Base, Height)); Console.Write("\nEnter the radius: "); Radius = double.Parse(Console.ReadLine()); Console.WriteLine("Moment of inertia of a semi-circle " + "with regard to the X axis: "); Console.WriteLine("I = {0}mm", MomentOfInertia(Radius)); Console.WriteLine(); return 0; } }
6. Execute the program. Here is an example:

 Enter the dimensions of the Rectangle Base: 4.25 Height: 2.55 Moment of inertia with regard to the X axis: I = 23.49028125mm Enter the radius: 5.35 Moment of inertia of a semi-circle with regard to the X axis: I = 321.717471644992mm
7. Close the DOS window
8. Here are the formulas considered for a triangle:

As you can see, the rectangle and the triangle are using the same dimension types. This means that we can provide only the same kinds of arguments, the base and the height, to calculate the moment of inertia. This also means that the compiler will not allow us to write two methods that have the same name, the same number of arguments, and the same types of arguments because that would violate the rule of function overloading.

In order to overload the MomentOfInertia() function, we will add an argument that will never be used; this argument will serve only as a “witness” to set the difference between both versions of the function. This “witness” argument can be anything: an integer, a character, a string, a float, etc. For our example, we will make it a simple integer. To use the version applied to the triangle, we will provide this argument to overload the MomentOfInertia() function. When called with only two arguments, the rectangle version will apply.

Change the file as follows:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; public class Exercise { // Rectangle static double MomentOfInertia(double b, double h) { return b * h * h * h / 3; } // Semi-Circle static double MomentOfInertia(double R) { const double PI = 3.14159; return R * R * R * R * PI/ 8; } // Triangle static double MomentOfInertia(double b, double h, int i) { return b * h * h * h / 12; } static int Main() { double Base = 7.74, Height = 14.38, Radius = 12.42; Console.WriteLine( "Rectangle - Moment of inertia with regard to the X axis: "); Console.WriteLine("I = {0}mm", MomentOfInertia(Base, Height)); Console.WriteLine("\nSemi-Circle - Moment of inertia of a " + "semi-circle with regard to the X axis: "); Console.WriteLine("I = {0}mm", MomentOfInertia(Radius)); Console.WriteLine("\nEnter the dimensions of the triangle"); Console.Write("Base: "); Base = double.Parse(Console.ReadLine()); Console.Write("Height: "); Height = double.Parse(Console.ReadLine()); Console.WriteLine( "\nTriangle - Moment of inertia with regard to the X axis: "); Console.WriteLine("I = {0}mm", MomentOfInertia(Base, Height, 1)); Console.WriteLine(); return 0; } }

9. Execute the program. Here is an example:

 Rectangle - Moment of inertia with regard to the X axis: I = 7671.78395376mm Semi-Circle - Moment of inertia of a semi-circle with regard to the X axis: I = 9344.28126291881mm Enter the dimensions of the triangle Base: 5.52 Height: 3.84 Triangle - Moment of inertia with regard to the X axis: I = 26.04662784mm
10. Close the DOS window
 Class Construction and Destruction

 Method Initializer

Imagine you are writing a program for a business that sells flowers:

 Flower Type Daisies Lilies Roses Live Plants Orchids Color White Mixed Red Green Pink Arrangement Vase Vase Bouquet Basket Vase Price 37.15 29.95 85.95 60.95 55.95

Consider the following program:

using System;

public class Flower
{
public int Type;
public int Color;
public char Arrangement;
public double UnitPrice;
}

public class Exercise
{
static int Main()
{
var flr = new Flower();

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

This would produce:

Flower Type:  0
Flower Color: 0
Arrangement:
Price:        \$0.00

Press any key to continue . . .

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

public class Flower
{
public int Type;
public int Color;
public char Arrangement;
public double UnitPrice;

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

The method initializer does not have to initialize all members of the class. For example, the previous execution of the program shows that the member variables that are of type string are initialized with empty strings. In such a case, you may not have to initialize such variables. To implement a method initializer, simply assign its argument to the corresponding member variable of the class. Here are examples:

public class Flower
{
public int Type;
public int Color;
public char Arrangement;
public double UnitPrice;

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

You can call a method initializer after declaring the instance of the class to give it initial values. Here is an example:

 using System; public class Flower { public int Type; public int Color; public char Arrangement; public double UnitPrice; public void Initializer(int tp, int clr, char arng, double price) { Type = tp; Color = clr; Arrangement = arng; UnitPrice = price; } } public class Exercise { static int Main() { var flr = new Flower(); flr.Initializer(3, 7, 'V', 37.15D); Console.WriteLine("Flower Type: {0}", flr.Type); Console.WriteLine("Flower Color: {0}", flr.Color); Console.WriteLine("Arrangement: {0}", flr.Arrangement); Console.WriteLine("Price: {0:C}", flr.UnitPrice); Console.WriteLine(""); return 0; } }

This would produce:

Flower Type:  3
Flower Color: 7
Arrangement:  V
Price:        \$37.15

Press any key to continue . . .

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

 Default Constructor

A constructor is a special method that is created when the object comes to life. This particular method holds the same name as the class and it initializes the object whenever that object is created. When you create a class, if you don't declare a constructor, the compiler creates one for you; this is useful because it lets all other objects of the program know that the object exists. This compiler-created constructor is called the default constructor. If you want, you can create your own constructor.

To create a constructor, declare a method that holds the same name as the class. Remember that the method must not return any value.

Here is an example:

namespace FlowerShop
{
public class Flower
{
Flower()
{
}
}
}

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

using System;

namespace FlowerShop
{
public class Flower
{
public int Type;
public int Color;
public char Arrangement;
public decimal UnitPrice;

public Flower()
{
Console.WriteLine("New Flower Order");
}
}

public class Exercise
{
static int Main()
{
var flr = new Flower();
return 0;
}
}
}

This would produce:

New Flower Order

Press any key to continue...

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

 The Constructor Initializer

A constructor can be used to initialize the member variables of a class. As such, a constructor provides a valuable alternative to a method initializer, the type of method we saw earlier. To use a constructor to initialize the member variables of a class, provide as arguments the necessary variables that you intend to initialize. You don't have to initialize all member variables in the constructor, only those that need to be initialized. In fact, you should initialize only those members that you think the other objects would need when using this object. This means that your object may have fields that, either the external objects don't need to modify (or access) or the member variable(s) will be initialized later when called from the needed object(s).

To implement a default constructor, you can just initialize the desired members of the class. For a member variable of a numeric type, you can just assign the desired constant to each. If the variable is a character, assign a single-quoted symbol to it. If the variable is a string, then assign a double-quoted value to the variable. Here are examples:

 using System; namespace FlowerShop { public class Flower { public int Type; public int Color; public char Arrangement; public decimal UnitPrice; public Flower() { Type = 1; Color = 1; Arrangement = 'V'; UnitPrice = 0M; } } public class Program { static int Main() { var flr = new Flower(); Console.WriteLine("Flower Type: {0}", flr.Type); Console.WriteLine("Flower Color: {0}", flr.Color); Console.WriteLine("Arrangement: {0}", flr.Arrangement); Console.WriteLine("Price: {0:C}", flr.UnitPrice); Console.WriteLine(""); return 0; } } }

The default constructor is the favorite place to provide default values to the members of a class. Besides the default constructor, you can add as many constructors as you judge necessary. This feature of C# allows you to create various constructors for different reasons. This also means that the methods or constructors of a class can be overloaded.

One of the rules of method overloading consists of having methods with different types of arguments. The most basic constructor you would create can use a single argument. When implementing a constructor that takes one argument, you should initialize the member that corresponds to the unique argument and initialize the other members with default values. Here is an example:

using System;

namespace FlowerShop
{
public class Flower
{
public int Type;
public int Color;
public char Arrangement;
public decimal UnitPrice;

public Flower()
{
Type        = 1;
Color       = 1;
Arrangement = 'V';
UnitPrice   = 0M;
}

public Flower(int tp)
{
Type        = tp;
Color       = 1;
Arrangement = 'V';
UnitPrice   = 0M;
}
}
}

If you create a class with only one constructor as in the current example, when declaring an instance of the class, you must use that constructor: you cannot use the default constructor that doesn't take an argument. When declaring the variable, initialize it with a constructor with parentheses and provide the value(s) in the parentheses of the constructor. Here is an example:

using System;

namespace FlowerShop
{
public class Flower
{
public string Type;
public string Color;
public string Arrangement;
public double UnitPrice;

public Flower()
{
Type        = "";
Color       = "Red";
UnitPrice   = 35.95D;
}

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

public class Exercise
{
static int Main()
{
var flr = new Flower("Tulips");

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

This would produce:

Flower Type:  Tulips
Flower Color: Red
Price:        \$35.95

Press any key to continue . . .

In the same way, you can create different constructors for different initializations, although it would not be realistic to create a different constructor for each variable. If you create different constructors with different arguments to initialize (remember the rules of method overloading), when declaring the classes, make sure you initialize each instance with the right number of arguments; otherwise, the compiler would complain.

If you create a class with only one constructor and that constructor has at least one argument, the default constructor would not be available anymore. If you want to access a default constructor of an object, you have two alternatives:

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

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

To create a destructor, type ~ followed by the name of the class. Here is an example:

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