C#.NET底层 List 集合循环添加对象(如:list.add(model)),为什么会出现整个list集合都是一样的数据?
2018-03-09 18:06
756 查看
先考考大家,这段代码,有没有问题?
发现了吗?这样写,把mod对象的实例化放在循环外面,最后的结果,就如我们题目中出现的,出来数据是一样的,并且就是最后一条数据。这是我们经常忽略的问题,因为出于性能考虑,我们一般把实例化对象写在循环外面,但是,便出现了这个问题,那么这是为什么呢?原因就是:代码中实例化mod对象时,内存中就把这一个mod对象存储在了堆上,并且在栈上分配了一个指向堆的地址;我们在一次次循环,改变mod的各个属性值的时候,其实是在改变堆,但是list.add(mod)的时候,添加mod对象,实际上是添加mod存在栈上指向堆的地址,地址自始至终没有发生改变,而堆上的数据,一直在被覆盖,直到最后一条数据;所以,到最后,我们分现,数据总数对,但是数据却是一样的,并且还都是最后一条的原因,就是这个!
我们只需要把实例化对象的操作,写在循环内部就好,这种情况下,不需要考虑对象的释放,在.NET底层机制下,垃圾回收机制已经成熟,例如这样的创建对象,在当次(i)循环结束时,就是立即释放,再进行下次(i+1)循环;
那么,我们有时又会见到这样的代码:
在这个时候,为什么mod对象的实例化,写在循环外面,但是最后数据却是正常的呢?这是因为每次循环时,mod的地址发生了改变,因为MapEntity方法都把一个新的mod,赋值给了我们看到的mod,这里赋值的便是栈上的地址;
----欢迎加入博主个人的技术交流QQ群:121942786(BUG制作者协会)
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制作者协会)
相关文章推荐
- C# List<T> Add方法循环添加时只保存了最后一次的数据(覆盖问题)
- 定义一个List集合并实例化对应的实现类对象。循环输入任意个整数,输入0结束输入循环,对集合中的数据进行从大到小的排序后输出
- List.add方法——向集合列表中添加对象
- List使用add方法添加对象-只显示最后添加的数据的问题
- 在List的add方法添加对象时都是最后的一条记录的重复
- 关于ASP.NET下,JQuery+AJAX使用JSON返回对象集合List数据的总结
- 在List的add方法添加对象时都是最后的一条记录的重复
- Java中对对象的操作是引用操作-建立Temp对象是,应该在循环里面new一个新的地址,再使用add添加到集合中去
- c# .Net :Excel NPOI导入导出操作教程之List集合的数据写到一个Excel文件并导出
- C# 对sharepoint 列表的一些基本操作,包括添加/删除/查询/上传文件给sharepoint list添加数据
- 使用ActiveReport for .net 进行报表开发--显示对象集合中的数据
- List和Hashtable都是可以存储数据的,可为什么有时选择List,有时需要Hashtable,这两个有什么区别
- .NET/C#中对自定义对象集合进行自定义排序的方法
- 使用 AddRange 方法将多个 ListItem 对象添加到集合
- 关于c# 泛型List集合对象的用法及相关操作
- C# 对sharepoint 列表的一些基本操作,包括添加/删除/查询/上传文件给sharepoint list添加数据
- NET C# List泛型集合 使用方法
- 为什么会出现这样的提示?错误在哪里?asp.net(C#)(1)
- 使用ActiveReport for .net 进行报表开发(三)--显示对象集合中的数据 (转)
- C# 对sharepoint 列表的一些基本操作,包括添加/删除/查询/上传文件给sharepoint list添加数据