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

C#中ListNode引用副本操作:为何有的修改影响原引用有的不?

引用类型变量操作的本质差异解析

先明确核心逻辑:C#里的引用类型变量,存储的是对象在内存中的地址(引用),而非对象本身。两个变量指向同一对象时,操作分为修改变量的引用指向和修改变量指向的对象的成员两类,这两种操作的结果完全不同。

第一种场景:CreateList函数中的temp操作

先看CreateList里的关键代码:

var root = new ListNode();
var temp = root; // temp和root指向同一个ListNode对象(记为对象A)

// 循环内的核心操作
while (temp.next != null)
    temp = temp.next; // 改变temp变量的指向:从对象A切换到A.next、A.next.next...

这里的temp = temp.next是给temp变量重新赋值,让它指向另一个对象,但root变量的指向始终是最初的对象A,所以root不会被改变。

而后续的temp.next = new ListNode(array[i]),是修改temp当前指向的对象的next成员,这个修改会同步到链表结构中,但root本身的指向还是对象A,所以返回的root依然是链表的头节点。

第二种场景:修改val的操作

再看这段测试代码:

var listNode1 = new ListNode(1); // 创建对象B,listNode1指向B
var listNode2 = listNode1; // listNode2也指向B
listNode2.val = 2; // 修改对象B的val成员
Console.WriteLine(listNode1.val); // 输出2,因为listNode1同样指向B

这里的listNode2.val = 2是直接修改listNode2指向的对象B的成员变量,由于listNode1和listNode2指向同一个对象B,所以通过listNode1访问val时,看到的是修改后的值。

总结差异

  • 执行temp = temp.next时,是改变temp变量自身的引用指向,和root变量的指向无关,因此root不受影响;
  • 执行listNode2.val = 2时,是修改共享对象的成员,所有指向该对象的变量都会同步看到修改结果。

可以用通俗的比喻理解:把对象比作房子,引用变量比作钥匙。

  • temp = temp.next相当于你把自己的钥匙换成了隔壁房子的钥匙,朋友手里的钥匙还是原来房子的;
  • listNode2.val = 2相当于你用钥匙打开房子,把里面的电视换成新的,朋友用他的钥匙开门,看到的也是新电视。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 05:12:46