Monday, July 7, 2008

Passing Reference in C#

In the article Passing Reference-Type Parameters, we've seen that we need to use the "ref" keyword in order to swap string values. This is also true for any other reference-types such as an ArrayList.

Remember:
When you pass a reference-type parameter by value, it is possible to change the data pointed to by the reference, such as the value of a class member. However, you cannot change the value of the reference itself; ...

This reminds me the differences between a reference and a pointer: In the swap function, if we are passing parameters by pointer(like in C or C++), then any local change is also global; if we are passing parameters by reference (like in C#), then any local change is not global.

2 comments:

Xiaoguang said...
This comment has been removed by the author.
Xiaoguang said...

private void AppendSB(StringBuilder sb)
{
// This change is global
sb.Append("Appended\n");
}

private void TrimString(string s)
{
// This change is local; use "ref" to make it global
s = s.Trim();
}

It is important to understand that string is immutable: each time we do any change to a string, we are actually assigning a new string value. StringBuilder is not immutable (like most reference type objects); so its state is maintained across function calls. However, for example, if we are swapping two objects such as two StringBuilders like below, we have to add "ref" keyword to make it work.

private void SwapSB(StringBuilder sb1, StringBuilder sb2)
{
StringBuilder temp = new StringBuilder();
temp = sb1;
sb1 = sb2;
sb2 = temp;
}

In essence, when we write "sb1 = sb2;", we are actually reassigning the reference of sb1. Now sb1 points to a complete different object. My understanding of why by default(not adding "ref" keyword) the change is local is: it is safer than letting the change be global. No matter what functions you call, they cannot change the object the reference originally points to.