Wednesday, September 29, 2010

Passing parameters with 'Val', 'Ref', 'Out'


Passing ValueType Parameters:

passing a value-type variable to a method means passing a copy of the variable to the method. Any changes to the parameter that take place inside the method have no affect on the original data stored in the variable. If you want the called method to change the value of the parameter, you have to pass it by reference, using the ref or out keyword. For simplicity, the following examples use ref.
  • Passing value types by value
  • Passing value types by reference
Passing value types by value:
The following example demonstrates passing value-type parameters by value. The variables Var1 and Var2 are passed by value to the method MyFunction. Any changes that take place inside the method have no affect on the original value of the variable.

Example1:
Take a windows application and add a button in the form.

int Var1 = 10;
int Var2 = 20;

private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Values in 'Var1' and 'Var2' Before calling the method : " + Var1.ToString() + " " + Var2.ToString());
MyFunction(Var1 , Var2 );
MessageBox.Show("Values in 'Var1' and 'Var2' After calling the method :" + Var1.ToString() + " " + Var2.ToString());
}

private void MyFunction(int a, int b)
{
a = 101;
b = 201;
MessageBox.Show("Values in 'Var1' and 'Var2' INSIDE the method :" + a.ToString() + " " + b.ToString());
}

Output:
Values in 'Var1' and 'Var2' Before calling the method : 10 20
Values in 'Var1' and 'Var2' INSIDE the method : 101 201
Values in 'Var1' and 'Var2' After calling the method : 10 20

Passing Value Types by Reference:
The following example is the same as Example 1, except for passing the parameter using the ref keyword. The value of the parameter is changed after calling the method.

Example2:
Take a windows application and add a button in the form.

int Var1 = 10;
int Var2 = 20;

private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Values in 'Var1' and 'Var2' Before calling the method : " + Var1.ToString() + " " + Var2.ToString());
MyFunction(
ref Var1 , ref Var2 );
MessageBox.Show("Values in 'Var1' and 'Var2' After calling the method :" + Var1.ToString() + " " + Var2.ToString());
}

private void MyFunction(ref int a, ref int b)
{
a = 101;
b = 201;
MessageBox.Show("Values in 'Var1' and 'Var2' INSIDE the method :" + a.ToString() + " " + b.ToString());
}

Output:
Values in 'Var1' and 'Var2' Before calling the method : 10 20
Values in 'Var1' and 'Var2' INSIDE the method : 101 201
Values in 'Var1' and 'Var2' After calling the method : 101 201

Passing Reference Type Parameters:

Passing Reference Types By Value:
The following example demonstrates passing a reference-type parameter, MyArr, by value, to a method, 'MyFunction'. Because the parameter is a reference to MyArr, it is possible to change the values of the array elements. However, the attempt to reassign the parameter to a different memory location only works inside the method and does not affect the original variable, MyArr.

Example3:
Take a windows application and add a button in the form.

private void button1_Click(object sender, EventArgs e)
{
int[] MyArr = {10,20,30};
MessageBox.Show("Value in 'MyArr[0]' Before calling the method : " + MyArr[0].ToString() );
MyFunction(
MyArr );
MessageBox.Show("Value in
'MyArr[0]' After calling the method :" +MyArr[0].ToString() );
}

private void MyFunction(
int[] a)
{
a[0] = 875; //this change afftets the original
a=new int[]{-12,-13,-14,-15,-17}; //this change is local
MessageBox.Show("Value in
'MyArr[0]' INSIDE the method :" + a[0].ToString() );
}

Output:
Value in 'MyArr[0]' Before calling the method : 10
Value in 'MyArr[0]' INSIDE the method : -12
Value in 'MyArr[0]' After calling the method : 875

Passing Reference Types By Reference:
This example is the same as Example 3, except for using the ref keyword in the method header and call. Any changes that take place in the method will affect the original variables in the calling program.

Example4:
Take a windows application and add a button in the form.

private void button1_Click(object sender, EventArgs e)
{
int[] MyArr = {10,20,30};
MessageBox.Show("Value in 'MyArr[0]' Before calling the method : " + MyArr[0].ToString() );
MyFunction(
ref MyArr );
MessageBox.Show("Value in
'MyArr[0]' After calling the method :" +MyArr[0].ToString() );
}

private void MyFunction(ref
int[] a)
{

//Both of the following will affect the original value.
a[0] = 875;
a=new int[]{-12,-13,-14,-15,-17};
MessageBox.Show("Value in
'MyArr[0]' INSIDE the method :" + a[0].ToString() );
}

Output:
Value in'MyArr[0]' Before calling the method : 10
Value in 'MyArr[0]' INSIDE the method : -12
Value in'MyArr[0]' After calling the method : -12

Difference between 'Ref' and 'Out'
:

ref requires that the variable be initialized before being passed, where as out need not be initialized before being passed.

The ref and out keywords are treated differently at run-time, but they are treated the same at compile time. Therefore methods cannot be overloaded if one method takes a ref argument and the other takes an out argument

Declaring an out method is useful when you want a method to return multiple values. A method that uses an out parameter can still return a value. A method can have more than one out parameter.

An overload will occur if declarations of two methods differ only in their use of ref. However, it is not possible to define an overload that only differs by ref and out. For example, the following overload declarations are valid:
class MyClass
{
public void MyMethod(int i)
{i = 10;}
public void MyMethod(ref int i)
{i = 10;}
}

but the following overload declarations are invalid:
class MyClass
{
public void MyMethod(out int i)
{i = 10;}
public void MyMethod(ref int i)
{i = 10;}
}

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.