【发布时间】:2010-01-28 17:21:44
【问题描述】:
我实际上是在尝试将多个项目添加到列表中,但最后所有项目的值都与最后一个项目相同。
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 更改为 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);
}
【问题讨论】:
标签: c#