有以下现象:

public class Chinese
{
    public string Name { get; set; }
    public int Age { get; set; }
    public int Height { get; }
}
 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

更多推荐