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

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

(首先,抱歉我的英语不好)

我正在尝试制作扑克牌游戏。
当代码 below.Those 函数洗牌时,
好像是call by reference,最后还是不行。

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

这是怎么回事?? 谢谢!

您应该在参数类型前加上 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

因为在方法参数中您实际上并没有仅传递值的引用,因此如果值在方法中发生更改,您的实际引用将不会受到影响。如果你想让它工作,你可以使用 ref/out 参数。

您可能听说过默认情况下对象是通过引用传递的,这是真的。但是,您不需要通过引用传递;您需要将引用传递给引用,因为swapTwoCards的重点不是更新对象而是更新对对象的引用。

要通过引用传递对象引用,请使用 ref 关键字。

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

默认情况下,C# 中的参数按值传递。引用类型的 "value" 是引用,透明的 "pointer" 用于定位实际数据。在 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或其他基本类型。请记住,参数默认为 by-value,因此您只能在方法内切换值。引用类型和 by-ref 参数传递没有任何共同点(嗯,当然 "reference" 除外)。