a DotNetStyling - .Net World by Armen Ayvazyan : Passing Parameter by Value and by Reference ("ref"). CLR Internals
Welcome to DotNetStyling Sign in | Join | Help
Add to Technorati Favorites Add to Google Reader or Homepage Add to My AOL Subscribe in FeedLounge Subscribe in Bloglines Add to Excite MIX Add to flurry Add to Pageflakes Subscribe in NewsGator Online


Passing Parameter by Value and by Reference ("ref"). CLR Internals

What is the difference between passing parameter by reference (using "ref" keyword) and by value (without using "ref" keyword)?

This is really nice and advance question which demonstrates understanding of .Net internals, especially relationship between Stack and Heap.

 

Reference Type

 

Let's make some demonstration and examine behavior and difference between passing reference type object by value and by reference.

First let's create some custom class which we will use in demonstration.

public class Book
{
       private decimal _price;
       public decimal Price
       {
              get { return _price; }
              set { _price = value; }
       }
}

 

Test

Now please look at the code below and say what is an expected output in both cases.

 

Passing Reference type by value

static void Main(string[] args)
{
       Book APress = new Book();
       APress.Price = 100;

       Book microsoftPress = APress;

       ChangePrice(APress);

       Console.WriteLine("Price of APress book is {0}",
                                    APress.Price);

       Console.WriteLine("Price of MicrosoftPress is {0}",
                                    microsoftPress.Price);

}            

static void ChangePrice(Book book)
{
       book.Price = 150;
       book = new Book();
       book.Price = 300;
}

 

 

Passing Reference type  by reference (using "ref" keyword)

static void Main(string[] args)
{
       Book APress2 = new Book();
       APress2.Price = 100;

       Book MicrosoftPress2 = APress2;

       ChangePriceRef(ref APress2);

       Console.WriteLine("Price of APress book is {0}",
                                   APress2.Price);

       Console.WriteLine("Price of MicrosoftPress is {0}",
                                    MicrosoftPress2.Price);

}

 

static void ChangePriceRef(ref Book book)
{
       book.Price = 150;
       book = new Book();
       book.Price = 300;

}

 

 

Output

Passing reference type by value

image

 

Passing reference type by reference

image

 

 

How does it work?

 

Case 1: Passing Reference type by value

When we are passing reference type by value (without ref keyword) we actually passing copy of the pointer in the stack which refer to the same object.

image

 

In the moment when we instantiated new Book we actually created new object in the Heap and changed reference of pointer. As a result we've got two objects in the Heap and appropriate pointers in the stack.

image

Now pointers are decoupled and any manipulations with book parameter will not reflect on APress.

 

Case 2: Passing Reference type by reference

In case of passing type by reference, "ref" keyword insurers that we are passing not a copy but original pointer.

So, when the moment of new Book instantiation came, we created new object and changed reference of pointer to the new object in the Heap:

image

As you can see, any manipulations after impact original APress.

 

 

 

Value Type

 

Test

Now we do the similar test but in this case will use primitive types.

 

Passing primitive type by value (without using ref keyword).

static void Main(string[] args)
{

int x = 10;
 
     int y = x;

       TestValueType(x);

       Console.WriteLine("x={0}", x);
 
      Console.WriteLine("y={0}", y);
}

static void TestValueType(int z)
{
       z = 5;
}

 

 

Passing primitive type by reference (using ref keyword).

static void Main(string[] args)
{
       int i = 10;
       int j = i;

       TestValueTypeRef(ref i);

       Console.WriteLine("i={0}", i);
 
      Console.WriteLine("j={0}", j);
}

static void TestValueTypeRef(ref int k)
{
       k = 5;
}

 

 

Output

Passing value type without ref keyword.

image

Passing value type with ref keyword

image

 

 

How does it work ?

When we passing value type parameter we are actually passing copy but not the original type. We are creating new  item in the stack and setting value which equals to original one. That is why any operation provided inside of the method does not impact the original type.

 

In case of using "ref" keyword CLR insures that original type will be passed to the method but not its copy. Which means any operation provided with input parameter will impact on the value of the original type. That is why in second case value of "i" field has been changed.

 



 

 
Technorati Tags: , ,



Share this post :

 

Posted: 22. listopadu 2007 21:35 by Armen Ayvazyan

Comments

New Comments to this post are disabled