Page 1 of 4
Passing parameters is easy as it always works in the same way but the effects aren't always the same. It can be confusing and even error prone unless you understand how it all works.
There is a new version of this article at:
The difference between a value and a reference type can be dangerous when passing parameters to a method. The rule is very simple, by default value types are passed by value and reference types are also passed by value! However when you pass a reference variable by value it look a lot like passing by reference. This sounds complicated but as long as you keep the idea of a value and a reference clear its not so difficult.
Pass by value
Consider first passing a value type by value. We have the usual PointV struct (see Chapter One) and a method that simply sets one of its fields to a value:
public struct PointV
Notice that the method has nothing to do with the struct - it is part of some other object. Next we create an instance of the struct using new to make sure its fields have been initialised:
PointV b=new PointV();
This results in a value variable b with it’s x field set to 5 as shown
If we now call MyMethod with b as parameter:
a new local variable a is created and initially set to the same value as b, then a.x is set to 10. The result is a local variable with its x field set to 10 as shown
Finally MyMethod terminates and all local variables are destroyed leaving only b with its values unchanged by the call as shown below.
Thus a call by value does not change the value of b the parameter passed into the method.
Now consider the reference type version of the same code i.e. what happens when you pass a reference type by value. In this case we need the class version of the point type and a suitably modified MyMethod:
As before we create an instance and set its x field to 5:
PointR b=new PointR();
This might look the same but as the diagram shows the situation is very different. Now we have a reference variable called b and its content is a reference to a PointR object created on the heap.
Now when we call MyMethod in exactly the same way,
b is passed by value which means that a new local variable a is created and the contents of b are copied to it. The big difference is now that the content of b is a reference to an object on the heap. The result is that we now have two reference variable referencing the object on the stack and when the assignment a.x=10 occurs in the method the object on the heap is changed as shown.
Once again when MyMethod terminates the behaviour is exactly the same. The local variables including a are destroyed but now the change made to the object on the heap persists as shown below.
You should now be able to appreciate that while both value and reference variables are passed by value the effect of making changes in the method are very different.
To summarise: by default parameters are always passed by value but passing a reference type allows the method to change the object of the reference. In each case however the value or reference of the passed variable isn’t changed.