Microsoft.NET

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

Parameter passing in C#

Posted by Ravi Varma Thumati on March 16, 2009

Value Types

 

The C# value types are the simple types, the enumerated types, and structs. The simple types   are bool, char, byte, sbyte, short, ushort, int, uint, long, ulong, float, double, and decimal. The C# language specification defines the range of values for each simple type and the set of operations supported by each type. The enumerated types   are declared using the C# enum construct. C# structs   are declared using the struct construct.

 

Every variable of a value type is a distinct instance of that type. Thus, an assignment statement such as

y = x;

 

Takes the value of the variable x and copies that value into the variable y. After the assignment, x and y remain distinct instances that happen to have equal values

 

A comparison of the form

 

if (x == y)

    {

/* tests whether the values contained in the variables x and y are equal…. */

}

References Types

 

In C#, every variable that is not one of the value types is a reference type. Such a variable can be thought of as a reference to (or a pointer to) an object of the appropriate type.

 

Every object to which a reference variable refers is an instance of some C# class. In C#, class instances must be explicitly created. An instance of a class is created using the new operator like this:

 

Foo f = new Foo();

If we follow this with an assignment statement such as

Foo g = f;

 

Then both f and g refer to the same object! Note that this is very different from what happens when you assign one value type to another.

 

A comparison of the the form

if (f == g)

    { /* … */ }

 

Usually tests whether the f and g refer to the same object instances (provided the equality operator has not been overriden). If f and g refer to distinct object instances that happen to be equal, the test still fails. To test whether two distinct object instances are equal, it is necessary to invoke the Equals method like this:

 

If (f.Equals(g))

    { /* … */ }

Null References

 

In C#, it is possible for a reference type variable to refer to nothing at all. A reference that refers to nothing at all is called a null reference. By default, an un-initialized reference is null.

 

We can explicitly assign the null reference to a variable like this:

 

f = null;

Also, we can test explicitly for the null reference like this

if (f == null)

    { /* … */ }

Parameter Passing

 

Parameter passing methods are the ways in which parameters are transferred between methods when one method calls another. C# provides two parameter passing methods–pass-by-value and pass-by-reference.

 

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 behaviour.

 

 

 

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

*/

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: