2010-10-08 49 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(); 
     }