C# 链表元素的引用地址分析

有以下现象:

cs 复制代码
public class Chinese
{
    public string Name { get; set; }
    public int Age { get; set; }
    public int Height { get; }
}
cs 复制代码
 var chiPersons = new List<Chinese>
 {
     new Chinese { Name = "张三", Age = 25 },
     new Chinese { Name = "李四", Age = 30 },
     new Chinese { Name = "王五", Age = 28 }
 };
 //创建新链表,使用存在的chiPersons 填充
 ObservableCollection<Chinese> MachinePositionList = new ObservableCollection<Chinese>(chiPersons);

 MachinePositionList[0].Age = 100;
//chiPersons 第一个元素会跟随更改
 var a = chiPersons[0].Age;


//看到chiPersons 第一个元素的Age也变成了100,
//我天真的以为两个链表的内存地址是一致的

 var newPerson = new Chinese { Name = "麻子" };
//向新链表中添加元素
 MachinePositionList.Add(newPerson);
//原链表长度不变
 var count = chiPersons.Count;


//同理,删除新链表的元素,原链表长度也不变
var zhangSan = MachinePositionList[0];
MachinePositionList.Remove(zhangSan);
 count = chiPersons.Count;

1. 内存结构图

复制代码
栈内存                    堆内存
─────────────────────────────────────────────────────
chiPersons变量  ──→  List<Chinese> 对象
                       ├─ 数组(元素是引用)
                       ├─ [0] ──→ Chinese对象A (张三,25)
                       ├─ [1] ──→ Chinese对象B (李四,30)
                       └─ [2] ──→ Chinese对象C (王五,28)

MachinePositionList变量 ──→ ObservableCollection<Chinese> 对象
                           ├─ 内部容器(元素是引用)
                           ├─ [0] ──→ 同上Chinese对象A ⬅ 共享!
                           ├─ [1] ──→ 同上Chinese对象B ⬅ 共享!
                           └─ [2] ──→ 同上Chinese对象C ⬅ 共享!

2. 关键内存行为

① 构造函数填充(浅拷贝)

csharp

复制代码
new ObservableCollection<Chinese>(chiPersons)
  • 只复制了引用 (指针),没有复制 Chinese 对象本身

  • 两个集合的每个槽位指向堆上同一组 Chinese 对象

② 修改元素属性

csharp

复制代码
MachinePositionList[0].Age = 100;
  • 通过 MachinePositionList[0] 拿到引用,顺着指针找到堆上的 Chinese 对象 A

  • 修改其 Age 字段

  • chiPersons[0].Age 也变成 100(因为是同一个对象)

③ 添加新元素

csharp

复制代码
MachinePositionList.Add(newPerson);
  • newPerson 指向新创建的 Chinese 对象 D(麻子)

  • ObservableCollection 在自己的内部数组末尾添加这个新引用

  • List<Chinese> 的内部数组长度不变(仍为 3)

  • 两个集合从此独立:各自维护自己的引用数组

3. 内存变化时序

操作 chiPersons内部数组 MachinePositionList内部数组 堆上对象
初始化 refA, refB, refC refA, refB, refC A, B, C
修改Age refA, refB, refC refA, refB, refC A(age=100), B, C
Add新元素 refA, refB, refC refA, refB, refC, refD A, B, C, D
相关推荐
rannn_1116 小时前
【力扣hot100】链表专题|160、206、234、141、142
java·算法·leetcode·链表·面试·开发
椒颜皮皮虾྅8 小时前
OpenVINO C# API 3.3.1:支持OpenVINO 2026.3及GenAI增强
人工智能·c#·openvino
LuminousCPP10 小时前
数据结构-双向循环链表
c语言·数据结构·笔记·链表
半亩码田11 小时前
C#转Python第3.1篇:Python 的 class 没有访问修饰符?面向对象的另一条路
开发语言·python·c#
唐青枫18 小时前
别再手写 args[0]:C#.NET CommandLineParser 命令行工具实战详解
c#·.net
LccKyI19 小时前
C#学习day06(方法/函数及其关键字,附思维导图)
经验分享·学习·c#
.Peter19 小时前
.NET/WPF 程序在部分 Windows 电脑无法保存用户环境变量:使用 DPAPI 实现安全兼容
windows·信息安全·c#·.net·wpf·环境变量·dpapi
(Charon)20 小时前
【C++】线程安全队列(三):MPSC无锁队列、atomic与链表节点实现
c++·安全·链表
农村小镇哥20 小时前
怎么把HTM格式转化成WORD
ui·c#·word
农村小镇哥20 小时前
C#读取CSV文件的方法
服务器·数据库·c#