我本质上是试图将多个项目添加到列表中,但最后所有项目的值都等于最后一个项目。
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
当我期望一个时设置为“Bar”"Foo"
和一个与"Bar"
. 为什么结果列表中的所有项目都具有相同的属性?
解释为什么要改变的加分public class Tag
to public struct Tag
使此代码按预期工作(不同的项目具有不同的值)。
如果这很重要,我的实际目标是创建派生集合类,但由于问题发生时仅列出它可能是可选的,因此仍然显示我的目标如下。
经过一些教程等之后,我能够成功创建一个集合类,该集合类继承了创建 DataTable 所需的功能,该 DataTable 可以作为表值参数传递到 Sql Server 的存储过程。一切似乎都进展顺利;我可以添加所有行,它看起来很漂亮。然而,经过仔细检查,我注意到当我添加新行时,所有先前行的数据都会被新行的值覆盖。因此,如果我有一行字符串值为“foo”,并且我添加了第二行值为“bar”,则将插入第二行(制作一个包含两行的 DataTable),但两行都将具有值“bar” ”。谁能明白为什么会这样吗?下面是一些代码,它可以工作,但已经被简化了一些(为了便于解释,已经减少了 Tag 类)。
以下是 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);
}