今天在做一個項目的時候,發現了這樣一個問題,為了讓大家看得更直接明了,我直接放代碼:
public void InsertObjectToList(){ List<NewsProtetype> list = new List<NewsProtetype>(); NewsProtetype info = new NewsProtetype(); DataTable dt = new DataTable(); KeywordUrlManage kum = new KeywordUrlManage(); dt = kum.GetKeywords(); if (dt.Rows.Count > 0) { for (int i = 0; i < dt.Rows.Count; i++) { info.keyword = dt.Rows[i][0].ToString(); info.url = dt.Rows[i][1].ToString(); list.Add(info); } } }
當你斷點調試的時候就會發現一個很嚴重的問題,那就是后一個info實體會不斷的覆蓋前一個實體,最后導致list集合里面的內容都是一樣的!當時我一時還不知道為什么會有這個結果,於是我又在for循環里面添加另一個集合記錄i的值,確有意思的發現這個是沒有被覆蓋的!一時間我是百思不得其解;后來我在網上查了,看到有人說是數據類型的區別:int是值類型,而上面是實體info是引用類型!這兩者的區別博客園的大牛們都寫了很多文章,也很詳細,其中我就注意到了這兩句:引用類型變量的賦值只復制對象的引用,而不復制對象本身。而將一個值類型變量賦給另一個值類型變量時,將復制包含的值。
我這里的實體是引用類型,也就是說我在for循環賦值的時候,一直都在同一個對象賦值add給List集合。所以不斷的給List添加同一個對象,自然會被不斷覆蓋前有的值,而值類型卻沒有
所以我就意識到解決這個bug其實只需要把for循環外面定義的實體類轉移到for循環內部就可以了,每添加一個實體對象就new一個出來保證不同;其正確的代碼如下:
public void InsertObjectToList(){ List<NewsProtetype> list = new List<NewsProtetype>(); DataTable dt = new DataTable(); KeywordUrlManage kum = new KeywordUrlManage(); dt = kum.GetKeywords(); if (dt.Rows.Count > 0) { for (int i = 0; i < dt.Rows.Count; i++) { NewsProtetype info = new NewsProtetype(); info.keyword = dt.Rows[i][0].ToString(); info.url = dt.Rows[i][1].ToString(); list.Add(info); } } }
PS:因為本人理論知識不強,不知道我理解對不對,或者說還不夠深層次!希望各位朋友指出來,讓我學習!謝謝了!
這是我第一篇技術博客,說來慚愧啊!畢業一年了,以前只是有問題的時候來博客園查資料......今后也會有時間更新博客的,這也是為了提高自己!!好了,就寫到這吧