为什么函数不会改变给定的节点(列表)?

Ema*_*l L 2 c# nodes

我目前在我的代码中有这个功能:

public static void GoToNextNode(Node<int> head)
{
    head = head.GetNext();
}
Run Code Online (Sandbox Code Playgroud)

这是我的主要功能:

Node<int> a1 = new Node<int>(5);
Node<int> a2 = new Node<int>(5,a1);
GoToNextNode(a2); // <---
Run Code Online (Sandbox Code Playgroud)

但是,在执行箭头标记的行之后,它不会在整个节点列表中移动到下一个对象.

函数本身有效,但只有当我让它返回下一个值时,它才能在主程序中起作用:

public static Node<int> GoToNextNode(Node<int> head)
{
    return head.GetNext();
}
Run Code Online (Sandbox Code Playgroud)

然后将主要功能更改为:

Node<int> a1 = new Node<int>(5);
Node<int> a2 = new Node<int>(5,a1);
a2 = GoToNextNode(a2); // <---
Run Code Online (Sandbox Code Playgroud)

任何想法为什么第一个选项不起作用?提前致谢!

Him*_*ere 5

将对象传递给方法时,实际上并没有将该对象本身传递给该方法,而只是将对象的引用传递给该方法.由于此引用本身是按传递的,因此在该方法中对它的任何修改都不会反映在外部.这与以下内容没有任何不同:

DoSomething(int i) 
{
    i = 3;
}
Run Code Online (Sandbox Code Playgroud)

您当然可以在方法中重新分配任何新值i.但是,任何客户端代码都不会反映这一点,它仍然只会看到传递给方法的完全相同的值.或者换句话说:你iDoSomething留下来做什么DoSomething,没有人会注意到它.

为了能够更改引用,您需要ref-keyword.简而言之,它允许您修改传递给您的方法的引用,以便在调用GotoNextNode参数后a2引用另一个实例:

public static void GoToNextNode(ref Node<int> head)
{
    head = head.GetNext();
}
Run Code Online (Sandbox Code Playgroud)

现在你可以像这样调用它:

GoToNextNode(ref a2);
Run Code Online (Sandbox Code Playgroud)

当 - 另一方面 - 你只想修改实例的成员时,你不需要ref,如下所示:

void DoSometjng(MyClass a)
{
    a.MyProperty = newValue;
}
Run Code Online (Sandbox Code Playgroud)

如您所见,您不是重新引用a,而只是修改底层对象.现在,使用此代码的人当然会看到该newValue对象内部.

  • 你在这里混合两件事.当然,您可以修改作为方法引用传递的对象的成员.但是你不能在方法中改变**引用**,除非你使用`ref`.因此,引用本身 - 也就是你传递给方法的东西 - 总是以**值**传递. (4认同)
  • C#总是按值传递,除非告知不要,它更安全 (3认同)
  • @EmanuelL通过向数组添加数字,您不会将**引用**更改为该数组,而只是将其内容(其成员)更改.为此,您不需要ref-keyword,对引用的*instance*所做的每个修改都会反映在对它的所有引用中. (3认同)