2017-02-04 3 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を持っていてください。この方法で

0

原因は値が実際の参照が影響されることはありませんメソッド内で変更されたので、もしあなたはactaullyだけの値の参照を渡していないパラメータ。 ref/outパラメータを使用することができます。

-1

オブジェクトがデフォルトで参照渡しされていると聞いたことがあります。ただし、参照渡しする必要はありません。 swapTwoCardsのポイントはオブジェクトを更新するのではなく、そのオブジェクトへの参照を更新するため、参照への参照を渡す必要があります。

refキーワードを使用し、参照することにより、オブジェクトの参照を渡します。

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

この用語は混乱します。何かは、あなたが 'ref'または' out'を渡したときに、それを参照すると言う以外は、デフォルトでは値によって渡されます。 __Passing by value__は、式の値をコピーし、そのコピーを渡すことを意味します。値タイプの「値」は、インスタンス全体、すなわち、全体としてとらえられた値タイプのすべての非静的フィールドのセットである。参照型の「値」が参照値です。したがって、参照型を値で渡すことは、参照をコピーすることを意味します。したがって、同じオブジェクトへの参照が2つあります。 __Passing by reference__は、同じ格納場所を使用することを意味します。 –

+0

私はOPの問題を読んで、伝統的な説明を読んで混乱していると思っています(なぜswapTwoCardsがうまくいくのでしょうか?)時には、すでに判明していることを繰り返すよりも、私が二重間接を指摘したとき、私は光が人々のために進むのを見ました。 –

0

デフォルトでは、C#の引数は値渡しです。参照型の「値」は、実際のデータの位置を特定するために使用される透過的な「ポインタ」という参照です。 swapTwoCardsでは、パラメータ内でポインタを入れ替えているだけで、メソッドの外側には影響しません。次の2つの変数の内容を交換したい、と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またはその他のプリミティブ型であると想像してみてください。引数は既定では値であることを忘れないでください。したがって、メソッド内の値のみを切り替えることになります。参照型とby-ref引数の受け渡しには共通点がありません(もちろん、「参照」を除く)。