Logo: C# Computing
 
Web CsharpComputing.com

C# Tutorial Lesson 5: Value types as References

There are several scenarios where we need to use value types as reference types:

Passing a value type to a method that takes a reference type, requires .NET boxing of the value type. The boxed value is copied into an opaque reference type and can only be accessed through un-boxing. Boxing/Unboxing in C# is done implicitly, but corresponds to special instructions in MSIL.

One frequently needs to modify a value type. As you may recall from Lesson2, value types are stored on the stack. So to modify a value type, we need modify the value stored in an address on the stack.

Here is a simple program that unsuccessfully attempts to modify an integer.

using System;
//does not change value of k
class Demo
{
   public class Test
   {
       public void change (int k)
       {
       k=k+2;
       }
   }
   public static void Main()
   {
      int i=3;
      Test hi=new Test();
      Console.WriteLine("Before {0} ", i);
      hi.change(i);
      Console.WriteLine("After {0} ", i);
   }
}

If you compile and execute this program, you will find that the value of the integer have not been changed by the method change. The reason is quite simple: method change takes a value of i, makes a copy of it, adds 2 to the copy and returns control to the main. Value of i does not change.When  change returns, its local copy of variable i disappears ( goes out of scope). When  Console.WriteLine("After {0} ",i); is called, it uses i which was never changed. A simple fix is to modify method change so that it returns a value:

 

using System;
// Circumvent the problem of changing value of i.
class Demo
{
    public class Test{
        public int change (int k)
        {
        return k+2;
        }
    }
    public static void Main()
    {
    int i=3;
    Test hi=new Test();
    Console.WriteLine("Before {0} ",i);
    Console.WriteLine("After {0} ", hi.change(i));
    }
}

The code above works fines but it does not change the value of i. To change we need to pass it by reference. When passing by reference compiler changes instead of changing a local copy. To do this we need to add keyword ref  indicating that change takes a reference as an argument.

using System;
class Demo
{
   public class Test{
      public void change(ref int k)
      {
         k=k+2;
      }
   }
   public static void Main()
   {
      int i=3;
      Test hi=new Test();
      Console.WriteLine("Before {0} ", i);
      hi.change(ref  i);
      Console.WriteLine("After {0} ", i);
   }
}

The output of this program is:

Before 3
After 5