Here, because a reference to y is
passed rather than its value, changes to the value of parameter x are
immediately reflected in y. In the above example, y ends up being null.
Compare this with the result of the same code without the ref modifiers. Now
consider the struct code we had earlier, but using reference parameters:
void Foo (ref IntHolder x) {
x.i=10;
}
...
IntHolder y = new IntHolder(); y.i=5;
Foo (ref y); Console.WriteLine (y.i);
EXAMPLE
using System; using System.Text;
public class Example7 { struct
IntHolder { public int i; }
// Note that Foo is declared static
here just // to make the sample app simple, so we don't // need
to instantiate the example class. This // has no bearing on the
parameter passing // discussed static void Foo (ref IntHolder x)
{ x.i=10; }
public static void Main (string[]
args) { IntHolder y = new IntHolder(); y.i=5;
Foo (ref y); Console.WriteLine (y.i); }
}
Output: 10
The two variables are sharing a storage
location, so changes to x are also visible through y, so y. i has the value 10
at the end of this code.
Note: what is the difference between
passing a value object by reference and a reference object by value?
You may have noticed that the last
example, passing a struct by reference, had the same effect in this code as
passing a class by value. This doesn't mean that they're the same thing,
however.
Consider the following code:
void Foo (??? IntHolder x) { x
= new IntHolder();
}
...
IntHolder y = new IntHolder(); y.i=5;
Foo (??? y);
In the case where IntHolder is a struct
(i.e. a value type) and the parameter is a reference parameter (i.e. replace ???
with ref above), y ends up being a new IntHolder value - i.e. y.i is 0. In
the case where IntHolder is a class (i.e. a reference type) and the parameter
is a value parameter (i.e. remove ??? above), the value of y isn't changed -
it's a reference to the same object it was before the function member call.
This difference is absolutely crucial
to understanding parameter passing in C#, and is why I believe it is highly
confusing to say that objects are passed by reference by default instead of
the correct statement that object references are passed by value by default.
|