Aditya Singh
Aditya Singh

Reputation: 9612

Swap two variables without using ref/out in C#

Is it possible to swap two variables without using ref/out keyword in C#(i.e. by using unsafe)?

for ex,

        swap(ref x,ref y);//It is possbile to by passing the reference

But, Is there any other way of doing the same thing. In the swap function you can use a temp variable. But, How to swap the variables without using ref/out keywords in C#?

Upvotes: 0

Views: 4593

Answers (8)

Zu1779
Zu1779

Reputation: 2198

With tuples

int a = 4, b = 8;
(a, b) = (b, a);

Upvotes: 3

user7011379
user7011379

Reputation:

here i am passing object as arguments

class person1
            {
                public int x, y;
                public person1(int x,int y)
                    {
                    this.x = x;
                    this.y = y;

                    }
                public void changes(person1 p1)
                {
                   // int t;
                    this.x = x + y;  //x=30 x=10,y=20
                    this.y = x - y;  //y=30-20=10
                    this.x = x - y; //x=30-10=20
                }
    }
     static void Main(string[] args)
       {
             person1 p1 = new person1(10,20);
             p1.changes(p1);
             Console.WriteLine("swapp hoge kya ?x={0} and y={1}", p1.x, p1.y);
             Console.ReadKey();
      }

Upvotes: 0

Ben Voigt
Ben Voigt

Reputation: 283624

No, it's not possible to affect variables* in the caller without the use of ref or out pass-by-reference. You could affect class members, but how would you know which ones you were being asked to swap?

*(You can affect instances of reference types and the changes will be visible to the caller, but instances are not "variables".)

Upvotes: 2

Daniel Mošmondor
Daniel Mošmondor

Reputation: 19956

I tried this

class Program
{
    static void Main(string[] args)
    {
        int x = 3;
        int y = 6;
        Console.Write(string.Format("before swap x={0} y={1}", x, y));
        Swap(x, y);
        Console.Write(string.Format("after swap x={0} y={1}", x, y));
        Console.ReadKey();
    }

    static public unsafe void Swap(int a, int b)
    {
        int* ptrToA = &a;
        int* ptrToB = &b;
        int c = a;
        *ptrToB = c;
        *ptrToB = *ptrToA;
    }
}

And completely forgot that ints are passed by value, and there is no way I can take a pointer of something that is actually COPIED from the caller to the callee stack.

so it doesn't work

So it seems, instead of being smarter, I just wasted some time but want to share that with you anyway :)

Upvotes: 1

Jon Hanna
Jon Hanna

Reputation: 113242

Not really, unless your only issue with ref is a dislike of the word itself.

You can swap through pointers, like:

public unsafe void Swap(int* x, int* y)
{
    unsafe
    {//lets not use a temp, just to be different!
        *x ^= *y;
        *y ^= *x;
        *x ^= *y;
    }
}

But really the only practical difference is all the pointer pitfalls that references save you from, along with the fact that it has to be unsafe. It's basically doing the same thing.

Upvotes: 1

snemarch
snemarch

Reputation: 5008

A (very!) contrived example using delegates:

class Program
{
    static void FunkySwap<T>(T a, T b, Action<T> setA, Action<T> setB)
    {
        T tempA = a;
        setA(b);
        setB(tempA);
    }
    static void Main(string[] args)
    {
        string s1 = "big";
        string s2 = "apples";
        Console.WriteLine("BEFORE, s1: {0}, s2: {1}", s1, s2);
        FunkySwap(s1, s2, a => s1 = a, b => s2 = b);
        Console.WriteLine("AFTER,  s1: {0}, s2: {1}", s1, s2);
    }
}

While the above is pretty silly, using a delegate setter method can be useful in other situations; I've used the technique for implementing undo/redo of property modifications.

Upvotes: 4

Aditya Singh
Aditya Singh

Reputation: 9612

I have tried using unsafe and it works, see the code

namespace ConsoleApplication2
{
class myclass
{
    public unsafe void swap(int *x, int *y)
    {
        unsafe
        {
            int temp = 0;
            temp = *x;
            *x = *y;
            *y = temp;
            Console.WriteLine("Using Swap1");
            Console.WriteLine("x:"+*x);
            Console.WriteLine("y:" + *y);
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        unsafe
        {
            int x = 10;
            int y = 20;
            int* t1 = &x;
            int* t2 = &y;
            myclass m1 = new myclass();
            m1.swap(t1,t2);
            Console.WriteLine("Main");
            Console.WriteLine("x: " + x);
            Console.WriteLine("y: " + y);
            Console.ReadLine();

        }
    }
}

}

Upvotes: 0

Michael
Michael

Reputation: 20049

You could pass the values in an object and return an instance of that object with the values swapped:

public struct Swapable
{
    public int A;
    public int B;
}

public Swapable Swap(Swapable swapable)
{
    return new Swapable()
    {
        A = swapable.B;
        B = swapable.A;
    };
}

Upvotes: 0

Related Questions