What is the use of "ref" for reference-type variables in C#?
I understand that if I pass a value-type (int
, struct
, etc.) as a parameter (without the ref
keyword), a copy of that variable is passed to the method, but if I use the ref
keyword a reference to that variable is passed, not a new one.
But with reference-types, like classes, even without the ref
keyword, a reference is passed to the method, not a copy. So what is the use of the ref
keyword with reference-types?
Take for example:
var x = new Foo();
What is the difference between the following?
void Bar(Foo y) {
y.Name = "2";
}
and
void Bar(ref Foo y) {
y.Name = "2";
}
You can change what foo
points to using y
:
Foo foo = new Foo("1");
void Bar(ref Foo y)
{
y = new Foo("2");
}
Bar(ref foo);
// foo.Name == "2"
There are cases where you want to modify the actual reference and not the object pointed to:
void Swap<T>(ref T x, ref T y) {
T t = x;
x = y;
y = t;
}
var test = new[] { "0", "1" };
Swap(ref test[0], ref test[1]);
Jon Skeet wrote a great article about parameter passing in C#. It details clearly the exact behaviour and usage of passing parameters by value, by reference (ref
), and by output (out
).
Here's an important quote from that page in relation to ref
parameters:
Reference parameters don't pass the values of the variables used in the function member invocation - they use the variables themselves. Rather than creating a new storage location for the variable in the function member declaration, the same storage location is used, so the value of the variable in the function member and the value of the reference parameter will always be the same. Reference parameters need the ref modifier as part of both the declaration and the invocation - that means it's always clear when you're passing something by reference.
Very nicely explained here : http://msdn.microsoft.com/en-us/library/s6938f28.aspx
Abstract from the article:
A variable of a reference type does not contain its data directly; it contains a reference to its data. 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; that is, you cannot use the same reference to allocate memory for a new class and have it persist outside the block. To do that, pass the parameter using the ref or out keyword.