Reputation: 801
(First of all , sorry for my poor English)
I was trying to make a Poker Card Game .
As the codes below.Those functions shuffle the deck ,
it seems call by reference , but finally it doesn't work.
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;
}
but if I write like this , it gets to work :
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;
}
}
What is going on ?? Thanks!
Upvotes: 2
Views: 1114
Reputation: 53958
You should prepend the arguments type with the ref
keyword:
private void swapTwoCards(ref PokerCardItem cardA, ref PokerCardItem cardB)
{
PokerCardItem temp = cardA;
cardA = cardB;
cardB = temp;
}
If you don't do this you just pass a copy of the corresponding references, when you call the method as below:
swapTwoCards(cardArray[i], cardArray[random.Next() % cardArray.Length]);
you can act only on the properties of the objects you pass. You can't change the reference that cardA
points to or cardB
points to.
Whereas you include the ref
keyword you can achieve that you want.
Furthermore, you have to make the above call as below:
swapTwoCards(ref cardArray[i], ref cardArray[random.Next() % cardArray.Length]);
Now you pass the values by reference and you can change the actual references, which is what you actually do in the body of your method.
For further reading, please have a look here.
Upvotes: 5
Reputation: 13177
By default, arguments in C# are passed by value. The "value" for the reference types is the reference, a transparent "pointer" that is used to locate the actual data. In swapTwoCards you are just swapping the pointers around in the parameters, it has no effect on the outside of the method. You want to swap the contents of two variables, and for that there is the ref
keyword:
private void swapTwoCards(ref PokerCardItem cardA, ref PokerCardItem cardB)
{
PokerCardItem temp = cardA;
cardA = cardB;
cardB = temp;
}
Decorated this way, the arguments are passed by reference to the actual variables that contain the values, and so the assignments modify the original variables. Use like this:
swapTwoCards(ref cardArray[i], ref cardArray[random.Next() % cardArray.Length]);
If you have troubles determining whether to put ref
in the parameters, try to imagine the types of the parameters be int
or other primitive type. Just remember that arguments are by-value by default, and so you would only switch the values inside the method. Reference types and by-ref argument passing have nothing in common (well, except the "reference", of course).
Upvotes: 0
Reputation: 52240
You may have heard that objects are passed by reference as default, and that is true. However, you do not need to pass by reference; you need to pass a reference to a reference, because the point of swapTwoCards
is not to update the object but to update the reference to the object.
To pass an object reference by reference, use the ref
keyword.
private void swapTwoCards(ref PokerCardItem cardA, ref PokerCardItem cardB)
{
Upvotes: -1
Reputation: 383
cause in method parameters you are not actaully passing reference just the values so if value is changed within method your actual reference won't be affected. you can use ref/out parameters if you want it to work.
Upvotes: 0