2017-02-04 46 views
2

(首先對不起我的英語不好)時
通過電話交換參考

我試圖做一個撲克紙牌遊戲不會在C#中工作。
由於代碼below.Those功能洗牌,
似乎通過引用調用,但最後它不工作。

private void disorderCards(PokerCardItem[] cardArray) 
    { 
     Random random = new Random(); 
     for (int t = 0; t < 10; t ++) 
      for (int i = 0; i < cardArray.Length; i ++) 
       swapTwoCards(cardArray[i], cardArray[random.Next() % cardArray.Length]); 
    } 

private void swapTwoCards(PokerCardItem cardA , PokerCardItem cardB) 
    { 
     PokerCardItem temp = cardA; 
     cardA = cardB; 
     cardB = temp; 
    } 

,但如果我寫這樣的,它開始工作:

private void disorderCards(PokerCardItem[] cardArray) 
    { 
     Random random = new Random(); 
     for (int i = 0; i < cardArray.Length; i ++) 
     { 
      int n = random.Next() % cardArray.Length; 
      PokerCardItem temp = cardArray[i]; 
      cardArray[i] = cardArray[n]; 
      cardArray[n] = temp; 
     } 
    } 

這是怎麼回事? 謝謝!

+0

C#默認通過值傳遞參數。如果你想通過引用來傳遞它們,你需要用'ref'或'out'關鍵字明確地說出來。 – InBetween

回答

4

你應該預先考慮的參數類型與ref關鍵字:

private void swapTwoCards(ref PokerCardItem cardA, ref PokerCardItem cardB) 
{ 
    PokerCardItem temp = cardA; 
    cardA = cardB; 
    cardB = temp; 
} 

如果你不這樣做,你只是傳遞相應的參考的副本,當你調用方法如下:

swapTwoCards(cardArray[i], cardArray[random.Next() % cardArray.Length]); 

您只能對所傳遞對象的屬性起作用。您不能更改cardA指向的引用或cardB指向的引用。

而你包括ref關鍵字就可以達到你想要的。

此外,你必須做出如下上述呼叫:

swapTwoCards(ref cardArray[i], ref cardArray[random.Next() % cardArray.Length]); 

現在,您可以通過參考通過值,你可以改變實際的參考,這是你真正做的你的方法的身體。

如要進一步瞭解,請看看here。在你沒有actaully順便提及剛剛值,因此如果值法在實際的參考範圍內改變方法參數

0

原因將不會受到影響。如果你想讓它工作,你可以使用ref/out參數。

-1

您可能聽說過,對象是通過引用作爲默認過去了,這是事實。但是,你不需要通過引用傳遞;您需要將引用傳遞給引用,因爲swapTwoCards的要點不是更新對象,而是更新對該對象的引用。

要通過參考一個對象的引用,使用ref關鍵字。

private void swapTwoCards(ref PokerCardItem cardA, ref PokerCardItem cardB) 
{ 
+0

這個術語很混亂。任何事情都是默認傳遞的,除非你在傳遞它時說'ref'或'out',那麼它將被引用。 __Passing by value__表示複製表達式的值並傳遞該副本。值類型的「值」是整個實例,也就是整個值類型的所有非靜態字段的集合。參考類型的「值」是參考。所以按值傳遞引用類型意味着複製引用,所以現在你有_two_引用同一個對象。 __Passing by reference__意味着使用相同的存儲位置。 –

+0

我讀到了OP的問題,並認爲他閱讀了傳統的解釋並且感到困惑(爲什麼他會認爲'swapTwoCards'會起作用?)有時候最好是用一種不同的方式來解釋事情,而不是重複已經被證明的事情被誤解了,當我指出雙重間接時,我已經看到了人們的光芒。 –

0

默認情況下,C#中的參數是按值傳遞的。引用類型的「值」是引用,一個透明的「指針」,用於定位實際數據。在swapTwoCards你只是交換參數中的指針,它對方法的外部沒有影響。你想交換兩個變量的內容,並針對存在的ref關鍵字:

private void swapTwoCards(ref PokerCardItem cardA, ref PokerCardItem cardB) 
{ 
    PokerCardItem temp = cardA; 
    cardA = cardB; 
    cardB = temp; 
} 

裝飾這種方式,參數參照包含的值,所以分配修改實際變量傳遞原始變量。使用這樣的:

swapTwoCards(ref cardArray[i], ref cardArray[random.Next() % cardArray.Length]); 

如果你有麻煩確定是否把ref中的參數,試着想象的參數類型是int或其他原始類型。請記住,默認情況下,參數是按值創建的,因此只能在方法內切換值。引用類型和通過引用參數傳遞沒有共同之處(當然,除了「引用」之外)。