我实质上是想将多个项目添加到列表中,但最后所有项目的值都等于最后一个项目。
public class Tag { public string TagName { get; set; } } List<Tag> tags = new List<Tag>(); Tag _tag = new Tag(); string[] tagList = new[]{"Foo", "Bar"}; foreach (string t in tagList) { _tag.tagName = t; // set all properties //Add class to collection, this is where all previously added rows are overwritten tags.Add(_tag); }
上面代码的两个项目与列表TagName设置为“栏”当我想到一个"Foo"和一个带"Bar"。 为什么所有项目在结果列表中都具有相同的属性?
TagName
"Foo"
"Bar"
解释这一点的加分点,为什么更改public class Tag为public struct Tag可使该代码按预期工作(不同的项目具有不同的值)。
public class Tag
public struct Tag
如果那件事我的实际目标是创建派生的集合类,但是由于仅列出该问题就可能产生问题,因此仍然显示了我的目标。
通过一些教程,我成功地创建了一个收集类,该类继承了创建DataTable所需的功能,该DataTable可以作为表值参数传递给Sql Server的存储过程。一切似乎都运行良好;我可以添加所有行,而且看起来很漂亮。但是,在仔细检查后,我注意到当我添加新行时,所有先前行的数据都会被新行的值覆盖。因此,如果我有一个字符串值为“ foo”的行,并添加了第二个值为“ bar”的行,则将插入第二行(制作一个包含两行的DataTable),但是这两行的值均为“ bar” ”。谁能知道为什么会这样吗?这是一些代码,
以下是Collection类的:
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); }
您在Tag循环内使用的是对象的相同实例,因此对的每次更新TagName都指向相同的引用。在循环内移动声明,以在循环的每个遍历上获取一个新鲜的对象:
Tag
foreach (string t in tagList) { Tag _tag = new Tag(); // create new instance for every iteration _tag.tagName = t; tags.Add(_tag); }
对于额外的部分- 当您Tag从复制操作更改class为struct复制操作(调用时发生)时,tags.Add(_tag)复制整个实例(本质上是创建一个新实例),与原始class情况不同,在原始情况下,仅将同一个实例的引用复制到调用的参数中,然后复制到列表的元素(有关如何传递给方法调用的说明,请参见C#按值传递与按引用struct传递)。
class
struct
tags.Add(_tag)