简体   繁体   English

交换时按引用调用在C#中不起作用

[英]Call by reference doesn't work in C# when swapping

(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! 谢谢!

You should prepend the arguments type with the ref keyword: 您应该在参数类型前面加上ref关键字:

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. 您不能更改cardA指向或cardB指向的参考。

Whereas you include the ref keyword you can achieve that you want. 而包括ref关键字则可以实现所需的效果。

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 . 如需进一步阅读,请在这里看看。

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. 如果希望它可以工作,则可以使用ref / out参数。

By default, arguments in C# are passed by value. 默认情况下,C#中的参数按值传递。 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. swapTwoCards中,您只是在参数中交换指针,这对方法的外部没有影响。 You want to swap the contents of two variables, and for that there is the ref keyword: 您想交换两个变量的内容,为此,有ref关键字:

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. 如果在确定是否将ref放入参数时遇到麻烦,请尝试将参数的类型想象为int或其他原始类型。 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). 引用类型和by-ref参数传递没有共同之处(当然,除了“引用”之外)。

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. 您需要将引用传递给引用,因为swapTwoCards目的不是更新对象,而是更新对对象的引用。

To pass an object reference by reference, use the ref keyword. 要通过引用传递对象引用,请使用ref关键字。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM