Reputation: 2491
What's the better way of implementing a swap function? How would using ref be better than using out, or vice versa? Any other benefits or drawbacks that will occur from using one or the other?
swapref(ref T a, ref T b) {
T temp = a;
a = b;
b = temp;
}
swapout(out T a, out T b)
{
T temp = a;
a = b;
b = temp;
}
Upvotes: 0
Views: 2017
Reputation: 16606
If I modify your swapout
method to something closer to compiling...
static void swapout<T>(out T a, out T b)
{
T temp = a; // ERROR: Use of unassigned out parameter 'a'
a = b; // ERROR: Use of unassigned out parameter 'b'
b = temp;
}
...it still produces the errors you see in the comments.
When a parameter is modified with out
it is treated as uninitialized and it is the responsibility of the method to assign it a definite value. The whole point of a swap method is to operate on values passed to it, but with out
the values of those parameters are off limits because the caller is not required to pass an initialized variable. Therefore, to answer your question, not only is using ref
the superior solution, but using out
is not a workable solution at all.
Upvotes: 1
Reputation: 300529
By definition a Swap()
function requires that the parameters passed have values. Therefore you should use ref
.
Using out
would imply that (and allow) uninitialized parameters could be passed (and in fact should not compile since you would be using an unassigned parameter)
Upvotes: 8
Reputation: 941317
Definite assignment is a big deal in C#, it keeps you out of trouble by ensuring that your code has assigned a value to a variable before it is used. The core reason that the language distinguishes between ref and out. Other languages don't draw this distinction, they just have syntax for "pass by value" vs "pass by reference". In VB.NET that's ByVal vs ByRef for example. By using out instead of ref you clearly state the data flow and promise that the variable doesn't have to be assigned before the call and will be assigned afterwards. The compiler verifies this and complains if you break that rule.
What you can't do is swap a "not assigned" state. No syntax exists that lets you express that a variable is not assigned after an operation. It therefore follows that you must use ref. Nullable gives you options, not in scope here.
Upvotes: 1