在做项目数据同步开发的时候,我碰到一个很奇怪的显现。我首先从数据库获取数据集DataSet然后用Model把数据封装,然后放到List<Model>中,最后我遍历List<Model>时发现,它里面只放了最后一条数据封装的model.我把代码贴出来如下:

///<summary>///学生实体类///</summary>classStudent{publicstringStuno{get;set;}publicstringName{get;set;}publicstringSex{get;set;}publicintAge{get;set;}publicstringPhone{get;set;}publicstringAddr{get;set;}publicDateTimeRegister_Time{get;set;}}

Studentstudent=newStudent();foreach(DataRowrowinds.Tables[0].Rows){student.Stuno=row["Stuno"].ToString();student.Name=row["Name"].ToString();student.Sex=row["Sex"].ToString();student.Age=Convert.ToInt32(row["Age"].ToString());student.Phone=row["Phone"].ToString();student.Addr=row["Addr"].ToString();student.Register_Time=Convert.ToDateTime(row["Register_Time"]);list.Add(student);}IEnumerator<Student>IEStu=list.GetEnumerator();Students=newStudent();while(IEStu.MoveNext()){s=IEStu.CurrentasStudent;Console.WriteLine("[{0}][{1}][{2}][{3}][{4}][{5}][{6}]",s.Stuno,s.Name,s.Sex,s.Age,s.Phone,s.Addr,s.Register_Time);}


尝试着去打断点测试,后来发现是自己的一个想当然给搞砸的。因为只要把Student student=new Student();放在foreach里面就不会有问题了。代码如下:

foreach(DataRowrowinds.Tables[0].Rows){Studentstudent=newStudent();//这语句解决了那个问题。student.Stuno=row["Stuno"].ToString();student.Name=row["Name"].ToString();student.Sex=row["Sex"].ToString();student.Age=Convert.ToInt32(row["Age"].ToString());student.Phone=row["Phone"].ToString();student.Addr=row["Addr"].ToString();student.Register_Time=Convert.ToDateTime(row["Register_Time"]);list.Add(student);}IEnumerator<Student>IEStu=list.GetEnumerator();Students=newStudent();while(IEStu.MoveNext()){s=IEStu.CurrentasStudent;Console.WriteLine("[{0}][{1}][{2}][{3}][{4}][{5}][{6}]",s.Stuno,s.Name,s.Sex,s.Age,s.Phone,s.Addr,s.Register_Time);}


正所谓知其然,也要知其所以然。现在我来分析下原因:

我的本意呢是想尽量少的分配内存空间去创建实例(优化性能的考虑),所以想通过一个model就作为中转,可是我没有理解对List<T>的真正原理。我本以为只要我把list.add(model)list就会拷贝一份model中的信息,实际上List<T>只是添加了一个指向model的地址指针,所以每次添加都会添加一个指向model的地址指针,但他们都指向了同一个地址。所以无论你中间add了多少,(期间,list的指针都指向model地址)只是取决于最后一条数据。


如果把Student student=new Student();放在foreach中那么每次都会去给model开辟一片内存空间,而list不在指向同一个地址,所以就不会造成数据被覆盖的假象了。


总结:

New 的含义就是开辟一片内存创建实例。

List<T> 中只是保存了一个指向地址指针。

最后我想告诉大家,数据结构很重要,有些东西很细微,如果不懂的话就很难找出其中的问题。如果我说的有什么不对的请和我分享你的看法。