2010-10-08 47 views
1

是否可以交换两个变量,而无需在C#中使用REF /出关键字(即,通过使用不安全的)?交换两个变量,而在C#中使用REF /出

为前,

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

但是,有没有这样做同样的事情的任何其他方式。在交换功能中,您可以使用临时变量。但是,如何在不使用C#中的ref/out关键字的情况下交换变量?

回答

4

A(!很)人为的例子使用委托:

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

虽然以上是非常愚蠢的,使用委托setter方法可以在其他情况下是有用;我已经使用该技术实现属性修改的撤销/重做。

+0

这是相当不错的(好吧,它非常可怕,但它作为一个答案很好),因为我们无法传递变量没有ref或ref ref与指针或对象遏制,你传递函数!良好的横向思维。 – 2010-10-08 09:50:16

+0

+1为时髦 – sloth 2010-10-08 09:57:20

+0

即使它看起来没有任何相似之处,这是迈克尔Shimmins的答案的副本。 – 2010-10-08 13:18:07

0

你可以在一个对象传递的价值和回报的价值观该对象交换的一个实例:在来电者

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

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

不,这不可能影响变量*不 使用 refout 传递参考。你可能会影响班级成员,但你怎么知道你被要求交换哪些成员?

*(可以影响引用类型的实例和变化将是可见的来电,但情况不是“变量”。)

+2

那么他询问是否不安全可以使用,因为不安全的代码块允许指针是不正确的说明它可以在没有ref或out的情况下完成 – 2010-10-08 06:11:46

+0

@Rune:您只是在不使用'ref'关键字的情况下创建一个传递参数的参数。那符合这个问题的信,我只是想知道它是否符合精神。 – 2010-10-08 13:16:15

0

我一直在使用不安全的尝试和它的作品,看到代码

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

不是真的,除非你有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; 
    } 
} 

但真正的唯一区别是所有的指针陷阱引用节省您的,与事实有不安全一起。它基本上是做同样的事情。

1

我想这

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的按值传递,有没有办法,我可以利用的东西,实际上是从主叫方到被叫堆栈复印的指针。

所以它不工作

这么看来的而不是更聪明,我只是浪费了一些时间,但仍要与大家分享:)

0

我在这里路过对象作为参数

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