2017-02-04 3 views
2

(Vor allem, sorry für mein schlechtes Englisch) Swapping
Anruf durch Verweis funktioniert nicht in C#, wenn

ich ein Poker-Kartenspiel zu machen versuche.
Wie die Codes unten. Diese Funktionen mischen das Deck,
es scheint Anruf per Referenz, aber schließlich funktioniert es nicht.

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

aber wenn ich so schreibe, wird es funktionieren:

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

Was ist los ?? Danke!

+0

C# übergibt standardmäßig Argumente nach Wert. Wenn Sie sie als Referenz übergeben möchten, müssen Sie dies explizit mit 'ref' oder' out' angeben. – InBetween

Antwort

4

sollten Sie prepend die Argumente mit dem ref Stichwort eingeben:

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

Wenn Sie dies nicht tun Sie nur passieren eine Kopie der entsprechenden Referenzen, wenn Sie die Methode, wie unten nennen:

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

Sie können nur auf die Eigenschaften der Objekte, die Sie übergeben. Sie können die Referenz, die cardA auf Punkte verweist, oder cardB nicht ändern.

Während Sie das Schlüsselwort ref hinzufügen, können Sie erreichen, dass Sie wollen.

Darüber, müssen Sie wie unten die oben Anruf:

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

Jetzt passieren Sie die Werte von Referenz und Sie können die tatsächlichen Referenzen ändern, das ist, was Sie tun, tatsächlich in der Körper Ihrer Methode.

Weitere Informationen finden Sie unter here.

0

Ursache In Methodenparameter übergeben Sie nicht einfach die Referenz nur die Werte, also wenn Wert innerhalb der Methode geändert wird, wird Ihre tatsächliche Referenz nicht beeinflusst. Sie können Ref/Out-Parameter verwenden, wenn Sie möchten, dass es funktioniert.

-1

Sie haben vielleicht gehört, dass Objekte per Referenz als Standard übergeben werden, und das ist wahr. Sie müssen jedoch nicht als Referenz übergeben werden. Sie müssen einen Verweis auf eine Referenz übergeben, da der Punkt das Objekt nicht aktualisiert, sondern den Verweis auf das Objekt aktualisiert.

Um eine Objektreferenz als Referenz zu übergeben, verwenden Sie das Schlüsselwort ref.

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

Diese Terminologie ist verwirrend. Alles wird standardmäßig als Wert übergeben, außer wenn Sie "ref" oder "out" sagen, wenn Sie es übergeben, dann wird es als Referenz verwendet. __Passing by value__ bedeutet, den Wert des Ausdrucks zu kopieren und diese Kopie zu übergeben. Der "Wert" eines Werttyps ist die gesamte Instanz, d. H. Die Menge aller nicht statischen Felder des Werttyps, die als Ganzes genommen werden. Der "Wert" eines Referenztyps ist die Referenz. Wenn Sie also einen Referenztyp nach Wert übergeben, bedeutet dies, dass Sie die Referenz kopieren, sodass Sie jetzt zwei Referenzen auf dasselbe Objekt haben. __Passing by Reference__ bedeutet, denselben Speicherort zu verwenden. –

+0

Ich lese das OP-Problem und denke, er liest die traditionelle Erklärung und ist verwirrt (warum sonst würde er denken, dass "swapTwoCards" funktionieren würde?) Manchmal ist es besser, die Dinge anders zu erklären, als etwas zu wiederholen, was bereits bewiesen wurde missverstanden, und ich habe das Licht für die Menschen gesehen, wenn ich auf die doppelte Indirektion hinweise. –

0

Standardmäßig werden Argumente in C# als Wert übergeben. Der "Wert" für die Referenztypen ist die Referenz, ein transparenter "Zeiger", der verwendet wird, um die tatsächlichen Daten zu lokalisieren. In swapTwoCards Sie vertauschen nur die Zeiger in den Parametern, es hat keine Auswirkungen auf die Außenseite der Methode.Sie möchten den Inhalt von zwei Variablen tauschen, und dafür gibt es das ref Stichwort:

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

diese Art und Weise verziert, die Argumente in Bezug auf die tatsächlichen Variablen übergeben werden, die die Werte enthalten, und so die Zuweisungen ändern die ursprünglichen Variablen. Verwenden Sie wie folgt aus:

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

Wenn Sie Probleme haben, zu bestimmen, ob ref in den Parametern zu setzen, versuchen Sie die Typen der Parameter sein int oder andere primitive Art vorzustellen. Denken Sie daran, dass standardmäßig Argumente als Wert angegeben sind. Daher würden Sie nur die Werte innerhalb der Methode wechseln. Referenztypen und By-Ref-Argument-Passing haben nichts gemeinsam (na ja, außer der "Referenz", natürlich).

Verwandte Themen