2010-01-28 73 views
11

下面的幾個教程和我能夠成功創建一個集合類,它繼承了創建一個DataTable所需的功能,可以傳遞給一個Sql Server的存儲過程作爲表值參數。一切似乎都運作良好;我可以添加所有的行,看起來很漂亮。但是,仔細觀察後,我注意到當我添加一個新行時,所有前面的行的數據將被新行的值覆蓋。因此,如果我有一個字符串值爲「foo」的行,並添加第二行的值爲「bar」,則會插入第二行(使兩行爲DataTable),但兩行的值都將爲「bar 」。任何人都可以看到爲什麼會這樣?這裏是一些代碼,它的工作原理雖然簡單一些(爲了便於解釋,Tag類已經縮小了)。爲什麼添加一個列表<>的新值覆蓋列表中的以前的值<>

以下是集合類的:

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Linq; 
using System.Web; 
using Microsoft.SqlServer.Server; 

namespace TagTableBuilder 
{ 
public class TagCollection : List<Tag>, IEnumerable<SqlDataRecord> 
{ 
    IEnumerator<SqlDataRecord> IEnumerable<SqlDataRecord>.GetEnumerator() 
    { 
     var sdr = new SqlDataRecord(
      new SqlMetaData("Tag", SqlDbType.NVarChar) 
      ); 

     foreach (Tag t in this) 
     { 
      sdr.SetSqlString(0, t.tagName); 

      yield return sdr; 
     } 
    } 
} 

public class Tag 
{ 
    public string tagName { get; set; } 
} 
} 

這些被稱爲如下:

//Create instance of collection 
TagCollection tags = new TagCollection(); 

//Create instance of object 
Tag _tag = new Tag(); 

foreach (string t in tagList) 
{ 
    //Add value to class propety 
    _tag.tagName = t; 
    //Add class to collection, this is where all previously added rows are overwritten 
    tags.Add(_tag); 
} 
+0

是的,我應該解決這個問題,謝謝! – 2010-01-29 17:16:22

回答

25

您使用內循環Tag對象的同一實例,因此每次更新tagName是相同的參考。移動聲明內循環,以獲得在每個循環過程新對象:

foreach (string t in tagList) 
{ 
    Tag _tag = new Tag(); 

    //Add value to class propety 
    _tag.tagName = t; 
    //Add class to collection, this is where all previously added rows are overwritten 
    tags.Add(_tag); 
} 

還要注意,我更新了最後一行添加_tag而不是mTag,因爲我沒有看到這個在任何地方定義。

2

在將標記添加到集合的循環中,您使用的是Tag的同一對象實例。實質上,您將tag的名稱設置爲tagList中的第一個值並將其添加到集合中,然後將相同Tag的名稱更改爲tagList中的第二個值,然後再將其添加到集合中。

您的標籤集合包含多個對同一個標籤對象的引用!在設置標籤名稱並將其添加到集合之前,每次在for循環內部實例化_tag。

相關問題