SamIAm
SamIAm

Reputation: 2491

Swap with out vs ref

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

Answers (3)

Lance U. Matthews
Lance U. Matthews

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

Mitch Wheat
Mitch Wheat

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

Hans Passant
Hans Passant

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

Related Questions