2012-08-02 38 views
1

我創建了一個需要2個輸出參數的方法。我注意到調用代碼可以爲兩個參數傳遞相同的變量,但是這種方法要求這些參數是分開的。我想出了我認爲是驗證這是真實的最佳方式,但我不確定它是否能100%地工作。這是我提出的代碼,嵌入了問題。如何驗證兩個輸出參數不指向相同的地址?

private static void callTwoOuts() 
{ 
    int same = 0; 
    twoOuts(out same, out same); 

    Console.WriteLine(same); // "2" 
} 

private static void twoOuts(out int one, out int two) 
{ 
    unsafe 
    { 
     // Is the following line guaranteed atomic so that it will always work? 
     // Or could the GC move 'same' to a different address between statements? 
     fixed (int* oneAddr = &one, twoAddr = &two) 
     { 
      if (oneAddr == twoAddr) 
      { 
       throw new ArgumentException("one and two must be seperate variables!"); 
      } 
     } 

     // Does this help? 
     GC.KeepAlive(one); 
     GC.KeepAlive(two); 
    } 

    one = 1; 
    two = 2; 
    // Assume more complicated code the requires one/two be seperate 
} 

我知道,解決這個問題的一個更簡單的方法,簡直是使用方法局部變量,只複製到末尾的輸出參數,但我很好奇,如果有是驗證一個簡單的方法地址,這是不需要的。

+2

另一個更簡單的方法是讓一個類來保存這兩個整數並返回這個類的單個實例。 – 2012-08-02 21:57:15

回答

5

我不知道爲什麼你曾經想知道它,但這裏有一個可能的黑客攻擊:

private static void AreSameParameter(out int one, out int two) 
{ 
    one = 1; 
    two = 1; 
    one = 2; 
    if (two == 2) 
     Console.WriteLine("Same"); 
    else 
     Console.WriteLine("Different"); 
} 

static void Main(string[] args) 
{ 
    int a; 
    int b; 
    AreSameParameter(out a, out a); // Same 
    AreSameParameter(out a, out b); // Different 
    Console.ReadLine(); 
} 

起初,我必須兩個變量設置爲任意值。然後將一個變量設置爲不同的值:如果另一個變量也發生了變化,那麼它們都指向相同的變量。

+0

這也是我的第一個想法 – 2012-08-02 22:03:31

相關問題