C# ref keyword usage
The clearest explanation I've ever run across for output and ref parameters is ... Jon Skeet's.
Parameter Passing in C#
He doesn't go into "best practices", but if you understand the examples he's given, you'll know when you need to use them.
When you may replace the original object, you should send him as ref
. If it's just for output and can be uninitialized before calling the function, you'll use out
.
Put succinctly, you would pass a value as a ref
parameter if you want the function you're calling to be able to alter the value of that variable.
This is not the same as passing a reference type as a parameter to a function. In those cases, you're still passing by value, but the value is a reference. In the case of passing by ref
, then an actual reference to the variable is sent; essentially, you and the function you're calling "share" the same variable.
Consider the following:
public void Foo(ref int bar)
{
bar = 5;
}
...
int baz = 2;
Foo(ref baz);
In this case, the baz
variable has a value of 5, since it was passed by reference. The semantics are entirely clear for value types, but not as clear for reference types.
public class MyClass
{
public int PropName { get; set; }
}
public void Foo(MyClass bar)
{
bar.PropName = 5;
}
...
MyClass baz = new MyClass();
baz.PropName = 2;
Foo(baz);
As expected, baz.PropName
will be 5, since MyClass
is a reference type. But let's do this:
public void Foo(MyClass bar)
{
bar = new MyClass();
bar.PropName = 5;
}
With the same calling code, baz.PropName
will remain 2. This is because even though MyClass
is a reference type, Foo
has its own variable for bar
; bar
and baz
just start out with the same value, but once Foo
assigns a new value, they are just two different variables. If, however, we do this:
public void Foo(ref MyClass bar)
{
bar = new MyClass();
bar.PropName = 5;
}
...
MyClass baz = new MyClass();
baz.PropName = 2;
Foo(ref baz);
We'll end up with PropName
being 5, since we passed baz
by reference, making the two functions "share" the same variable.