You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#递归编程中类的引用行为:链表生成时变量指向差异问题

问题描述

现有可接收int类型数组、将其转换为递归链表对象的ListGenerator实现,代码如下:

public class ListNode
{
    public int val;
    public ListNode next;
    public ListNode(int x) { val = x; }
    public ListNode(int val = 0, ListNode next = null)
    {
        this.val = val;
        this.next = next;
    }
}

public static ListNode GenerateList(int[] nums)
{
    if (nums == null || nums.Length == 0) { return null; }

    var i = 0;
    var first = new ListNode(nums[i]);
    var current = first;

    while (++i < nums.Length)
    {
        current.next = new ListNode(nums[i]);
        current = current.next;
    }

    return first;
}

已知C#中的类为引用类型,执行current.next = new ListNode(nums[i]);代码后,first变量会与current同步变化,该表现符合预期。
但执行current = current.next;后,first与current的值不再一致:实际表现为first的next属性已被赋值,但current的next属性为null。按照对引用类型的常规认知,first应当与current始终保持一致,该实际表现与认知存在偏差,需要明确该现象的底层原理。

核心原理

你对引用类型的认知存在一个关键误区:引用类型变量本身只是存储堆内存地址的「指针」,两个变量指向同一个对象时,修改对象的属性会在所有引用处同步可见,但给变量本身重新赋值,只会改变当前变量存储的地址,不会影响其他变量,也不会修改原对象的内容。

逐行拆解代码执行逻辑就能完全理清现象:

  • 初始化阶段:执行var first = new ListNode(nums[i]); var current = first;时,栈上的两个引用变量first和current存储了完全相同的堆内存地址,都指向刚创建的第一个链表节点,此时两个变量确实指向同一个对象。
  • 执行current.next = new ListNode(nums[i]);时:逻辑是通过current存储的地址找到堆上的第一个节点,修改这个节点的next字段,让它指向新创建的第二个节点。由于first也指向这个第一个节点,因此通过first访问next时自然能看到修改后的值,这就是你观察到的「同步变化」。
  • 执行current = current.next;时:这一步没有修改任何堆上的节点对象,只是把栈上current变量存储的内存地址,替换为current.next对应的地址——也就是刚创建的第二个节点的地址。此时两个变量的指向已经完全分离:
    • first存储的地址没有任何变化,仍然指向第一个节点,第一个节点的next字段仍然保留着指向第二个节点的引用
    • current已经不再指向第一个节点,转而指向刚创建的第二个节点,而新节点初始化时next默认值为null,因此此时访问current.next得到的就是null

可以用一个生活化的类比辅助理解:你把自己家的地址写在两张便签上,一张标注first,一张标注current。你拿着current便签找到家,在门上贴了一张写着邻居家地址的纸条(对应修改节点的next属性),这时候不管拿哪张便签找到你家,都能看到门上贴的邻居地址。之后你把current便签上的地址涂改成邻居家的地址,这时候current便签指向的是邻居家,邻居家门上本来就没贴其他地址纸条(对应next为null),但first便签上还是你家的地址,你家门上的邻居地址纸条也没有被改动,两张便签对应的内容自然就不再一致。

内容的提问来源于stack exchange,提问作者user4661780

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 03:33:08