为何List<T>中添加的对象引用未随字段初始化同步更新?
问题:List中添加未初始化的引用字段后,初始化原字段为何列表项仍为null?
我在Form1类中定义了未初始化的引用类型字段cl1(MyCl1 cl1;),将cl1添加到List<MyCl1>集合后,调用init_cl1()方法完成cl1的初始化,但列表中的对应项依然是null。我原本以为列表中的引用会关联到新创建的MyCl1对象,请问这是为什么?
代码示例
public partial class Form1 : Form { public Form1() { InitializeComponent(); List<MyCl1> l_my = new List<MyCl1>(); l_my.Add(cl1); init_cl1(); MyCl1 my2 = l_my[0]; // my2=null } MyCl1 cl1; //========================================== private void init_cl1() { cl1 = new MyCl1(); } } public class MyCl1 { }
解答
核心原因:引用类型的赋值逻辑
问题本质是引用类型变量存储的是对象的内存地址,而非对象本身:
- 执行
l_my.Add(cl1)时,cl1还未初始化,值为null(空内存地址),所以你是把null添加到了列表中。 - 调用
init_cl1()时,cl1 = new MyCl1()只是改变了cl1这个变量的指向——让它指向新创建的MyCl1对象的内存地址,但列表里存储的还是之前的null值,两者没有任何关联。
简单来说:列表里存的是添加时cl1的即时值(null),后续修改cl1的指向不会自动同步到列表中。
两种解决思路
先初始化字段,再添加到列表
确保添加到列表时cl1已经指向有效的对象:public Form1() { InitializeComponent(); init_cl1(); // 先完成初始化 List<MyCl1> l_my = new List<MyCl1>(); l_my.Add(cl1); // 添加已初始化的引用 MyCl1 my2 = l_my[0]; // my2此时为新创建的MyCl1对象 }手动更新列表中的引用
如果必须先添加再初始化,在init_cl1()后手动把列表对应位置的值替换为更新后的cl1:public Form1() { InitializeComponent(); List<MyCl1> l_my = new List<MyCl1>(); l_my.Add(cl1); init_cl1(); l_my[0] = cl1; // 手动同步列表中的引用 MyCl1 my2 = l_my[0]; // my2此时为新创建的MyCl1对象 }
内容的提问来源于stack exchange,提问作者FaikeProgramer
相关产品推荐
相关产品推荐

