Поменяйте местами две переменные без использования ref / out в C # - PullRequest
0 голосов
/ 08 октября 2010

Можно ли поменять местами две переменные, не используя ключевое слово ref / out в C # (то есть, используя небезопасное)?

для ex,

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

Но, есть ли другой способделать то же самое.В функции подкачки вы можете использовать переменную temp.Но как поменять переменные без использования ключевых слов ref / out в C #?

Ответы [ 8 ]

4 голосов
/ 08 октября 2010

Придуманный (очень!) Пример с использованием делегатов:

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);
    }
}

Хотя вышесказанное довольно глупо, использование метода установщика делегата может быть полезно в других ситуациях; Я использовал технику для реализации отмены / повтора изменений свойств.

2 голосов
/ 08 октября 2010

Нет, невозможно повлиять на переменные * в вызывающей стороне без использования ref или out передачи по ссылке. Вы могли бы повлиять на учеников, но как бы вы узнали, кого из них попросили поменяться?

* (Вы можете повлиять на экземпляры ссылочных типов, и изменения будут видимы для вызывающей стороны, но экземпляры не являются «переменными».)

1 голос
/ 08 октября 2010

Я попробовал это

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;
    }
}

И полностью забыл, что int s передаются по значению, и нет никакого способа, которым я могу взять указатель чего-то, что на самом деле COPIED от вызывающего к вызываемомустек.

так что он не работает

Так что, кажется, вместо того, чтобы быть умнее, я просто потратил немного времени, но все равно хочу поделиться этим с вами :)

1 голос
/ 08 октября 2010

Не совсем, если только ваша единственная проблема с ref не относится к самому слову.

Вы можете менять местами указатели, например:

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

Но на самом деле единственное практическое отличие - все ловушки указателей, от которых вас спасут ссылки, а также тот факт, что это должно быть небезопасно. Это в основном то же самое.

0 голосов
/ 03 мая 2018

с кортежами

int a = 4, b = 8;
(a, b) = (b, a);
0 голосов
/ 25 февраля 2017

здесь я передаю объект в качестве аргументов

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();
      }
0 голосов
/ 08 октября 2010

Я пытался использовать unsafe, и он работает, см. Код

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();

        }
    }
}

}

0 голосов
/ 08 октября 2010

Вы можете передать значения в объекте и вернуть экземпляр этого объекта с замененными значениями:

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

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