C#.NET底层 List 集合循环添加对象(如:list.add(model)),为什么会出现整个list集合都是一样的数据?

先考考大家,这段代码,有没有问题?

            stuModel mod = new stuModel();
            while (dr.Read())
            {
                mod.DDID = dr["DDID"].ToString();
                mod.CPfenlei = dr["CPfenlei"].ToString();
                mod.CPguige = dr["CPguige"].ToString();
                mod.CPMach = (int)dr["CPMach"];
                mod.CPName = dr["CPName"].ToString();
                mod.CPyanse = dr["CPyanse"].ToString();
                list.Add(mod);
            }

发现了吗?这样写,把mod对象的实例化放在循环外面,最后的结果,就如我们题目中出现的,出来数据是一样的,并且就是最后一条数据。这是我们经常忽略的问题,因为出于性能考虑,我们一般把实例化对象写在循环外面,但是,便出现了这个问题,那么这是为什么呢?
原因就是:代码中实例化mod对象时,内存中就把这一个mod对象存储在了堆上,并且在栈上分配了一个指向堆的地址;我们在一次次循环,改变mod的各个属性值的时候,其实是在改变堆,但是list.add(mod)的时候,添加mod对象,实际上是添加mod存在栈上指向堆的地址,地址自始至终没有发生改变,而堆上的数据,一直在被覆盖,直到最后一条数据;所以,到最后,我们分现,数据总数对,但是数据却是一样的,并且还都是最后一条的原因,就是这个!

我们只需要把实例化对象的操作,写在循环内部就好,这种情况下,不需要考虑对象的释放,在.NET底层机制下,垃圾回收机制已经成熟,例如这样的创建对象,在当次(i)循环结束时,就是立即释放,再进行下次(i+1)循环;
            while (dr.Read())
            {
                stuModel mod = new stuModel();
                mod.DDID = dr["DDID"].ToString();
                mod.CPfenlei = dr["CPfenlei"].ToString();
                mod.CPguige = dr["CPguige"].ToString();
                mod.CPMach = (int)dr["CPMach"];
                mod.CPName = dr["CPName"].ToString();
                mod.CPyanse = dr["CPyanse"].ToString();
                list.Add(mod);
            }

那么,我们有时又会见到这样的代码:
            stuModel mod = new stuModel();
            while (dr.Read())
            {
                mod = Class1.MapEntity<stuModel>(dr, properties);//此方法的返回值就是stuModel
                list.Add(mod);
            }

在这个时候,为什么mod对象的实例化,写在循环外面,但是最后数据却是正常的呢?
这是因为每次循环时,mod的地址发生了改变,因为MapEntity方法都把一个新的mod,赋值给了我们看到的mod,这里赋值的便是栈上的地址;


----欢迎加入博主个人的技术交流QQ群:121942786(BUG制作者协会)
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值