I am new with C# and I can't understand why this code doesn't work.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
char[] sw = "ab".ToCharArray();
swap(sw[0], sw[1]);
string end = new string(sw);
Console.Write(end);
}
static void swap(char a, char b)
{
char temp = a;
a = b;
b = temp;
}
}
}
What I expect on console is "ba" but I get "ab". I was able to find different approach to solve this problem but what I would like to know is what is the mistake in this code.
Thanks for the help!
The problem is that the swap
method is actually just manipulating local copies of a
and b
. You need to pass the arguments by reference. So you would define the swap
method like this:
static void swap(ref char a, ref char b)
{
char temp = a;
a = b;
b = temp;
}
And call it like this:
swap(ref sw[0], ref sw[1]);
It should be modified like the following (Note: in this example, ref char[] arr
is prefixed with ref
mostly for didactic purpose: array will be passed by ref
by default)
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
char[] sw = "ab".ToCharArray();
swap(0, 1, ref sw );
string end = new string(sw);
Console.Write(end);
}
static void swap(int indexA, int indexB, ref char[] arr)
{
char temp = arr[indexA];
arr[indexA] = arr[indexB];
arr[indexB] =temp;
}
}
}
Your swap is taking two value types and swapping the values between the variables. There's nothing there that would modify the original array. You would need to modify your swap method to something like:
static void Swap(char[] array, int a, int b)
{
char temp = array[a];
array[a] = array[b];
array[b] = temp;
}
You could then call it from Main() like:
Swap(array, 0, 1);
A more generic array swap function:
public static void Swap<T>(this T[] array, int indexA, int indexB)
{
T temp = array[indexA];
array[indexA] = array[indexB];
array[indexB] = temp;
}
Also, a generic function to swap several array elements:
public static void Swap<T>(this T[] array, int indexA, int indexB, int length)
{
while (length-- > 0)
Swap(array, indexA++, indexB++);
}
You are passing your arguments a
and b
by value.
See What's the difference between passing by reference vs. passing by value? for more information.
Here are two solutions to fix your issue.
//Pass by value and return the values
static Tuple<char, char> swap2(char a, char b)
{
char temp = a;
a = b;
b = temp;
return new Tuple<char, char>(a, b);
}
//Pass by reference
static void swap3(ref char a, ref char b)
{
char temp = a;
a = b;
b = temp;
}
public static void Main(string[] args)
{
char[] sw2 = "ab".ToCharArray();
var chars2 = swap2(sw2[0], sw2[1]);
sw2[0] = chars2.Item1;
sw2[1] = chars2.Item2;
//Will print "ba"
Console.WriteLine(sw2);
char[] sw3 = "ab".ToCharArray();
swap3(ref sw3[0], ref sw3[1]);
//Will print "ba"
Console.WriteLine(sw3);
}
Here's a question about whether you should use or try to avoid the ref keyword. Aside from the simplest uses, it's often advised to avoid ref when possible. Swap falls into the category of "simplest uses," but I suggest that you try to avoid using ref in most practical situations.
When is using the C# ref keyword ever a good idea?