Search This Blog

Loading...

Wednesday, December 16, 2009

Ref and Out Parameters In C#


Value Parameters

Passing Value Types by Value

We often call the class methods through the class instances and by passing parameters. These parameters have all been passed by value. While we pass the value types of a parameter, 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 method parameter by value and the parameter's value is changed within the method, but the original variable remains unaffected.

Public class CallMathod
{

public void CallMethod()
{
    int original = 100;
    CallingMathod obj = new CallingMathod();           
    obj.showValue(original);
    Label1.Text="Original: "+ original.ToString();;
}
}
 
Public class CallingMathod
{
 
static void showValue(int valueToShow)
{
    valueToShow *=2;
    Label2.Text="Double: "+ valueToShow.ToString();
}
}
 OUTPUT
 
Double: 200
Original: 100
 

Passing Reference Types by Value

When we pass the reference types by value rather value 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 the same 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 "StudentClass" class that contains a single property for the student's roll number. When calling the GetRollNumber method, the Student is passed by reference. Increasing the Roll Number property within the method is visible outside of the method too. However, when the GetNewNumber method is called, the reassigned object is not seen externally to the method.

Public class CallMathod
{

public void CallMethod()
{
        Student objStudent = new Student ();
        objStudent.rollNumber = 004512;
 
        GetRollNumber(objStudent);
        Label1.Text ="Roll Number: "+ objStudent.rollNumber;
 
        GetNewNumber(objStudent);
        Console.WriteLine("Roll Number: {0}", objStudent.rollNumber);
 
         OUTPUT
 
        Diameter: 004513
        Diameter: 004513
 
        
 
}
 
    static void GetRollNumber(Student objSt)
    {
        objSt.rollNumber++;
    }
 
    static void GetNewNumber(Student objSt)
    {
        objSt = new Student();
        objSt.rollNumber = 1;
    }
 
}
 
Public class Student
{
 
    private int _rollNumber;
    
    public int rollNumber
    {
        get
        {
            return _rollNumber;
        }
        set
        {
            _rollNumber = value;
        }
    }
 
 
}
 


 
 

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 CalleeMethod()
{
    int original = 100;
    CallingMathod obj = new CallingMathod();         
    obj.showValue(ref original);              
    Label1.Text = "Original: "+original.ToString();
}
 
Public class CallingMathod
{
 
static void showValue(int valueToShow)
{
    valueToShow *=2;
    Label2.Text="Double: "+ valueToShow.ToString();
}
}
 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 Student class to use reference parameters, this can be demonstrated. In the following code the student’s rollNumber is increased by 1 as is was previously with the reference parameters showing no apparent difference in functionality. When the GetNewNumber method is called, the student variable is reassigned as a completely new object.

Public class CallMathod
{

public void CallMethod()
{
        Student objStudent = new Student ();
        objStudent.rollNumber = 004512;
 
        GetRollNumber(ref objStudent);
        Label1.Text ="Roll Number: "+ objStudent.rollNumber;
 
        GetNewNumber(objStudent);
        Console.WriteLine("Roll Number: {0}", objStudent.rollNumber);
 
         OUTPUT
 
        Diameter: 004513
        Diameter: 000001
 
        
 
}
 
    static void GetRollNumber(ref Student objSt)
    {
        objSt.rollNumber++;
    }
 
    static void GetNewNumber(ref Student objSt)
    {
        objSt = new Student();
        objSt.rollNumber = 000001;
    }
 
}
 
Public class Student
{
 
    private int _rollNumber;
    
    public int rollNumber
    {
        get
        {
            return _rollNumber;
        }
        set
        {
            _rollNumber = value;
        }
    }
 
 
}
 


Output Parameters

When we need to return more than one value from a method, 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 behavior 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.

static void CalleeMethod()
{
    decimal x = 10.00;
    decimal y = 200.00;
    decimal area;
    decimal perimeter;
 
    CallingMathod obj = new CallingMathod();         
    area =obj.GetArea(x,y,out perimeter);     
        
    Label1.Text = "Area: "+ area.ToString();
    Label2.Text = "Perimeter: "+ perimeter.ToString();
 
}
 
Public class CallingMathod
{
 
static decimal GetArea(int x,int y,out int perimeter)
{
    perimeter = 2*(x+y);
    return (x*y);
}
}
 OUTPUT
 
Area: 2000.00
Perimeter: 420.00
 



Colclussion:
OUT :

Variable gets value initialized after going into the method.
Later the same value is returned to the main method.
Ref :
Variable should be initialized before going into the method.
Later same value or modified value will be returned to the main method