Microsoft.NET

……………………………………………….Expertise in .NET Technologies

Functional Methods in C# (OOP’s) – Part 6

Posted by Ravi Varma Thumati on July 13, 2009

Functional Methods in C#

This article expands upon the creation of methods described in the previous article. In this article, the creation of methods that return a value and that can accept parameters is considered.

Functional Methods

In C# methods were created in order to centralize standard tasks, increasing the readability and maintainability of the code. However, these methods worked in isolation only as there was no facility to pass information to the function using parameters and no value returned on completion of the call. Although this is useful, most of the methods that you create will require the use of parameters, return values or both.

Creating a Method that Returns a Value

In the previous article, we created a method that obtained the current date and time and outputted it to the console in a desired format. In this article, we will create a similar method that returns the date and time rather than outputting it. Methods can be created that use any value type or reference type for the return value. In this case, the formatted date and time will be returned as a string.

A method with a return value is declared in a similar manner to a variable. The variable type is indicated first, followed by the name of the method and a pair of parentheses (). The code for the method is then appended within a code block. The code to declare our empty example method is therefore as follows:

string GetFormattedDate()

{

}

To return a value to the calling procedure, the return command is used. The return command is followed by the value or object that is to be passed back, as follows:

string GetFormattedDate()

{

DateTime theDate = DateTime.Now;

return theDate.ToString(“dd/MM/yyyy”);

}

Now that the method has been created, it can be called in the same manner as any other method. If you are using a standard console application, the default class will be called Program and will now contain a Main method as well as GetFormattedDate. To use the new method, you must first create a new Program object and call its GetFormattedDate function, assigning the result to a variable. This can be controlled within the Main method making the final code as follows:

static void Main(string[] args)

{

Program p = new Program();

string outputDate = p.GetFormattedDate();

Console.WriteLine(outputDate);              // Outputs “26/07/2007”

}

string GetFormattedDate()

{

DateTime theDate = DateTime.Now;

return theDate.ToString(“dd/MM/yyyy”);

}

Adding Parameters

So far, all of the methods created in the tutorial can only perform a single task and their operation cannot be configured. By adding parameters to a method, information can be passed from the calling function to control the processing.

Any number of parameters may be added to the definition of a method by declaring each parameter within the method’s parentheses, separated by commas. Each parameter must have a defined data type that is declared using the same syntax as when creating an uninitialised variable.

The parameters of a method behave differently according to the type of data they convey. For parameters that are declared as value types, a copy of the parameter’s information is passed to the method. This means that if a variable is used as a parameter and the value is modified within the method, the value of the variable in the calling method is unaffected. However, if a parameter is of a reference type and receives an instance of a class, a copy of the reference to the object is passed to the method. Any change to the parameter variable that occurs within the method will therefore also be seen outside of the method. This is because both references are pointing to the same data in the computer’s memory.

For this example, we will create a method that accepts two parameters that define the width and height of a rectangle. The two values will be multiplied to obtain the rectangle’s area and the resultant value returned. Firstly, the method is defined with the return value and the two parameters specified. Note that the parameters are defined in lower camel case where the initial letter of each word in a name is capitalised, with the exception of the first word that is entirely lower case. This is a useful convention for variable naming though not strictly necessary.

int GetArea(int rectHeight, int rectWidth)

{

return rectHeight * rectWidth;

}

The method may now be called with the parameter values specified. The following example demonstrates this:

static void Main(string[] args)

{

Program p = new Program();

int area = p.GetArea(10, 5);                // Outputs “50”

Console.WriteLine(area);

}

int GetArea(int rectHeight, int rectWidth)

{

return rectHeight * rectWidth;

}

Static Methods

In the example above, a new object of the class Program was created so that the method declared could be executed. You may have noticed that the Main method was declared differently to the OutputFormattedDate method with the addition of the static prefix. This prefix declares the method as a static method, meaning that no object needs to be created before the method is called. By prefixing the new method with the same static keyword, we can remove the requirement to create a Program object.

static void Main(string[] args)

{

int area = GetArea(10, 5);                  // Outputs “50”

Console.WriteLine(area);

}

static int GetArea(int rectHeight, int rectWidth)

{

return rectHeight * rectWidth;

}

C# Method Parameters

In this article, the various types of parameter that can be added to a method definition are described.

Value Parameters

Passing Value Types by Value

So far we have created methods that accept parameters and return a single value. These parameters have all been passed by value. In the case of passing value types, this means that a copy of the value’s contents has been passed. As only a copy of the contents is available, the external variable’s value cannot be modified from within the method.

The following example code demonstrates the use of value parameters with variables that are value types. In this sample, a value type variable is declared and its value is assigned. This variable is then used as the value of a parameter. The variable is passed to the parameter by value and the parameter’s value is changed within the method, but the original variable remains unaffected.

static void Main(string[] args)

{

int original = 100;

showDouble(original);

Console.WriteLine(“Original: {0}”, original);

}

static void showDouble(int valueToShow)

{

valueToShow *=2;

Console.WriteLine(“Double: {0}”, valueToShow);

}

/* OUTPUT

Double: 200

Original: 100

*/

Passing Reference Types by Value

In the case of passing reference types by value, a copy of the reference is made. This means that any changes to the object’s properties that occur within the method will be reflected outside of the method too. This is because both the external variable and the variable within the method contain matching references to the same underlying object data in memory. However, if the variable inside the method is assigned a completely new value, and therefore a different reference to the external variable, this change is not reflected outside of the method.

To demonstrate, consider the following code. This uses a “Ball” class that contains a single property for the ball’s diameter. When calling the InflateBall method, the Ball is passed by reference. Increasing the diameter property within the method is visible outside of the method too. However, when the GetNewBall method is called, the reassigned object is not seen externally to the method.

You can test this code by creating a new console application and copying in the Program and Ball class definitions. NB: This code is for demonstration purposes only and should not be considered as well structured.

class Program

{

static void Main(string[] args)

{

Ball football = new Ball();

football.Diameter = 15;

InflateBall(football);

Console.WriteLine(“Diameter: {0}”, football.Diameter);

GetNewBall(football);

Console.WriteLine(“Diameter: {0}”, football.Diameter);

/* OUTPUT

Diameter: 16

Diameter: 16

*/

}

static void InflateBall(Ball ball)

{

ball.Diameter++;

}

static void GetNewBall(Ball ball)

{

ball = new Ball();

ball.Diameter = 1;

}

}

class Ball

{

private int _diameter;

public int Diameter

{

get

{

return _diameter;

}

set

{

_diameter = value;

}

}

}

NB: If a value parameter uses a reference type, changes to the properties of the object are reflected outside of the method in most cases. An example where this is not true would be for the immutable string class, which is designed to act like a value type in some of its behavior.

Reference Parameters

Passing Value Types by Reference

An alternative to passing parameters by value is passing by reference. When using reference parameters for value types a copy of the value is not made. Instead, the variable used in the parameter is itself passed to the called method. This makes the behaviour similar to using reference types in value parameters; any changes to the value of the parameter variable is also seen outside of the method.

A reference parameter is declared using the ref keyword before the parameter type and name. This prefix is also used when calling the method.

The following sample code is based upon the first example in this article but by using a reference parameter rather than a value parameter, the results seen are different.

static void Main(string[] args)

{

int original = 100;

showDouble(ref original);

Console.WriteLine(“Original: {0}”, original);

}

static void showDouble(ref int valueToShow)

{

valueToShow *=2;

Console.WriteLine(“Double: {0}”, valueToShow);

}

/* OUTPUT

Double: 200

Original: 200

*/

Passing Reference Types by Reference

Reference type data can be passed to reference parameters. In this case, rather than passing a copy of the reference to the method, as when using value parameters, the reference variable itself is passed. In this situation, property changes within the method are reflected outside of the method as expected. However, if the variable is reassigned within the method, the variable outside of the method is also reassigned.

By modifying the earlier example relating to the Ball class to use reference parameters, this can be demonstrated. In the following code the ball is inflated as is was previously with the reference parameters showing no apparent difference in functionality. When the GetNewBall method is called, the ball variable is reassigned as a completely new object. This is mirrored in the Main method of the program also.

class Program

{

static void Main(string[] args)

{

Ball football = new Ball();

football.Diameter = 15;

InflateBall(ref football);

Console.WriteLine(“Diameter: {0}”, football.Diameter);

GetNewBall(ref football);

Console.WriteLine(“Diameter: {0}”, football.Diameter);

/* OUTPUT

Diameter: 16

Diameter: 1

*/

}

static void InflateBall(ref Ball ball)

{

ball.Diameter++;

}

static void GetNewBall(ref Ball ball)

{

ball = new Ball();

ball.Diameter = 1;

}

}

class Ball

{

private int _diameter;

public int Diameter

{

get

{

return _diameter;

}

set

{

_diameter = value;

}

}

}

Output Parameters

There are some occasions where it is useful to return more than one value from a method. Where this is the case, one value can be returned using the normal return command with additional values being extracted using output parameters.

An output parameter is declared using the out keyword before the parameter type and name. When called, the out keyword is used again as a prefix to the variable being passed as a parameter. The behaviour seen is similar to passing by reference in that the variable must be assigned a value within the method. This value will then be reflected in the output parameter.

The following code includes a method that uses a return value to return the area of a rectangle. It returns the perimeter of the rectangle using an output parameter. Note that, unlike with a reference parameter, the variable does not need to be assigned before use.

static void Main(string[] args)

{

int area;

int perimeter;

area = CalculateRectangle(5, 10, out perimeter);

Console.WriteLine(“Area: {0}”, area);

Console.WriteLine(“Perimeter: {0}”, perimeter);

}

static int CalculateRectangle(int width, int height, out int perimeter)

{

perimeter = (width * 2) + (height * 2);

return width * height;

}

/* OUTPUT

Area: 50

Perimeter: 30

*/

NB: This code is provided to show an example of output parameters. It would be unusual to create such a method in a real program as it would be more readable to create separate methods for the area and perimeter calculations.

Parameter Arrays

The final type of method argument is the parameter array. This must be the last parameter in a method definition. A parameter array declaration indicates that any number of parameters of the indicated type may be used in the method call, allowing for optional parameters. Each value passed to the parameter is combined into a standard array that can be processed within the method.

To declare a parameter array, the params keyword is used as a prefix. The parameter is also declared as a one-dimensional array by appending a pair of square brackets to the data type in the method definition.

The following example declares a method with a single string parameter and a parameter array consisting of integers. Any number of integer values, include none at all, may be used when calling the method.

static void Main(string[] args)

{

showScores(“Bob”, 15);

showScores(“Jill”, 10, 12, 15, 25);

showScores(“Ken”);

}

static void showScores(string player, params int[] scores)

{

Console.WriteLine(“Player: {0}”, player);

foreach (int score in scores)

Console.Write(“{0}\t”, score);

Console.WriteLine(“\n”);

}

/* OUTPUT

Player: Bob

15

Player: Jill

10      12      15      25

Player: Ken

*/

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: