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
相关推荐
hoiii1871 小时前
C# Txt/Excel/Access 导入导出工具
开发语言·c#·excel
专注VB编程开发20年2 小时前
TFTP 与FTP核心区别:UDP和TCP
c#·tftp
yi念zhi间2 小时前
C#实现控制台多区域输出
开发语言·c#
2501_930707782 小时前
使用 C# 在 Excel 中合并并居中单元格
开发语言·c#·excel
feifeigo1232 小时前
C# ADB 安卓设备数据传输工具
android·adb·c#
xiaoshuaishuai82 小时前
C# 逆向分析Privazer
数据库·microsoft·c#
baivfhpwxf20233 小时前
雷赛(Leadshine)EtherCAT 数字 I/O 模块(如 EMC-E5064-8)的状态指示灯(I/O 状态)说明
c#·wpf
JaydenAI3 小时前
[MAF预定义Agent中间件-05]ToolApprovalAgent-摆脱重复审批的烦恼
ai·c#·agent·maf·agent中间件