Raja
Raja

Reputation: 429

Why do I need to pass strings by reference to my swap function?

In C#, string is a reference type. Then,

Why do I need to have my swap function to have ref parameters?

swap(ref string first, ref string second) //swap(string first, string second) doesn't work
{
     temp = first;
     first = second
     second = temp;
}

Upvotes: 3

Views: 1836

Answers (6)

Eric Lippert
Eric Lippert

Reputation: 660128

You are confusing two different kinds of references. Strings are references to instances. Your swap function takes references to variables.

Think about it this way. You have two books, "A Christmas Carol" and "Pickwick Papers". They're books; they've got pages and text and whatnot.

You have ten pieces of paper. Five says "A Christmas Carol". Five says "Pickwick Papers". The papers are references to the books. They're not the books.

You have ten drawers labelled A, B, C, D, E, F, G, H, I, J. You put the papers that says "A Christmas Carol" into drawer A through E, and the papers that says "Pickwick Papers" into drawers F through J.

Now you want to swap the contents of drawers E and I. What information do you have to give to the swapper? You can't tell the swapper "Swap references to Christmas Carol for Pickwick Papers", because that would change all ten drawers, not just E and I. The information you have to give to the swapper is "E" and "I". You have to pass reference to two variables; the fact that the variables themselves contain a reference to a book is irrelevant.

Your swapper has three drawers of its own, labelled first, second and temp. It takes two piece of paper. One says "E", and that goes in the drawer labelled "first". One says "I" and that goes in the drawer labelled "second".

The swapper looks in "first" and finds a paper that says "E". It looks in "E" and finds a paper that says "Christmas Carol". It makes a photocopy of that paper and puts the copy in "temp"... and you see how this goes from here I hope.

Upvotes: 7

Henrik
Henrik

Reputation: 23324

Yes, string is a reference type and this

void swap(string first, string second)

passes references to the string objects to the function. But string is immutable so it is not possible for the swap function to change the objects through these references. For strings, the only way to implement a swap function is to use the ref keyword to pass the references by reference so the references can be swapped.

OTOH, if you have a mutable class, you can write a swap function without using the ref keyword:

class Foo
{
    public int Bar { get; set; }
}

static void Swap(Foo first, Foo second)
{
    var temp = first.Bar;
    first.Bar = second.Bar;
    second.Bar = temp;
}

Foo foo1 = new Foo { Bar = 1 };
Foo foo1Copy = foo1;
Foo foo2 = new Foo { Bar = 2 };
Swap(foo1, foo2);

But note, that after the swap, foo1Copy.Bar == 2, since the object referenced by foo1 and foo1Copy was modified.

Upvotes: 3

Yogesh P
Yogesh P

Reputation: 331

String is a reference type. It is passed by value to the method by default. If you actually want to change the value of the string, you need to pass it by reference. The below msdn article explains it in detail. http://msdn.microsoft.com/en-us/library/s6938f28(v=vs.80).aspx

Upvotes: 0

The reference to the string is passed by value. There's a big difference between passing a reference by value and passing an object by reference. It's unfortunate that the word "reference" is used in both cases.

Upvotes: 3

Samuel Slade
Samuel Slade

Reputation: 8613

If you pass an object into a method, you are passing the actual object and not the address in memory of the object. You could not then assign a new value to it as you would be changing what object is stored in a memory address elsewhere, not the original.

By adding the ref keyword, you pass the objects by reference. This means you essentially give the method access to the address where the objects are stored, so when you swap the objects, the original memory addresses will then refer to the swapped object.

Upvotes: 0

Tudor
Tudor

Reputation: 62439

Because parameters in C# by default are passed by value, not reference. Adding ref gives you pass-by-reference behavior.

Upvotes: 3

Related Questions