我有一些代码,我过去几天一直在为朋友工作。在较高级别,它解析文本文件并写入MDB。简而言之,我有一对嵌套的循环对这些项目进行一些处理。内环只在某些情况下被调用,但是当它发生时,它正在做一些奇怪的事情。
ArrayList CaseRecordItems = new ArrayList(); // this is created earlier
string baseTif = "sometext_"; // this is created earlier
CaseRecord cr = new CaseRecord(); (this gets populated with "stuff")
char increment = 'A';
for (int i = 0; i < FirstNames.Count; i++)
{
cr.Firstname = (string)FirstNames[i];
cr.Lastname = (string)LastNames[i];
if (FirstNames.Count > 1)
{
cr.Tif = baseTif + increment.ToString();
increment++;
}
CaseRecordItems.Add(cr);
}
循环运行两次,并且应该将cr.Tif的值设置为sometext_A和sometext_B。这样可以正常工作,但是一旦第二个项目添加到集合中,第一个项目的值就会更改为与之匹配。
我怀疑这是因为我不了解这些对象是如何被实例化和传递的。任何见解都将不胜感激。
修改
基于令人敬畏的反馈(以及我的麻木)这个问题已经解决了。感谢Dan的回答,我在使用克隆功能之前对我尝试过的代码进行了一些更改(是的,我实际尝试过的海滩:P)。
新块看起来像这样: ArrayList CaseRecordItems = new ArrayList(); //这是先前创建的 string baseTif =“sometext_”; //这是先前创建的 CaseRecord cr = new CaseRecord(); //这会填充“东西”) char increment ='A';
for (int i = 0; i < FirstNames.Count; i++)
{
CaseRecord cr2 = new CaseRecord();
cr2 = cr.Clone(); // preserves the data from outside
cr2.Firstname = (string)FirstNames[i];
cr2.Lastname = (string)LastNames[i];
if (FirstNames.Count > 1)
{
cr2.Tif = baseTif + increment.ToString();
increment++;
}
CaseRecordItems.Add(cr2);
}
感谢大家的超快响应!
答案 0 :(得分:7)
我认为cr是一个对象。你不是每次都创建一个新的cr,所以你在arraylist中有两次相同的引用,因此当你第二次实际处理同一个对象时修改它。
答案 1 :(得分:2)
您正在更改循环内cr
实例的值。循环中的每次迭代都使用cr
的相同实例,因此当您更改它时,它们都会发生变化。要解决此问题,一种合适的方法是在循环中使用本地实例:
for (int i = 0; i < FirstNames.Count; i++)
{
CaseRecord cr=new CaseRecord();
...
CaseRecordItems.Add(cr);
}
答案 2 :(得分:1)
问题是变量cr在循环中两次都是相同的,所以通过循环两次都修改了同一个对象,并且同一个对象被添加到ArrayList两次。
您没有显示足够的代码来显示声明cr的位置。
你需要做类似的事吗
for (int i = 0; i < FirstNames.Count; i++)
{
CRObject cr = new CRObject();
cr.Firstname = (string)FirstNames[i];
cr.Lastname = (string)LastNames[i];
if (FirstNames.Count > 1)
{
cr.Tif = baseTif + increment.ToString();
increment++;
}
CaseRecordItems.Add(cr);
}
答案 3 :(得分:1)
cr对象是否具有克隆功能?
如果是这样,应该这样做:
CaseRecordItems.Add(cr.Clone());
答案 4 :(得分:0)
由于cr没有得到新的声明(我不知道cr的类型或者我会告诉你),你只是反复添加相同的引用。如果你想将新的cr项添加到CaseRecordItems,那么你新建一个cr = new TypeOfCR();否则你只是一遍又一遍地覆盖同一个对象。
编辑:请务必在循环中执行新操作
答案 5 :(得分:0)
如果你没有在for循环中创建cr(不管它是什么),那么每次循环时你都会反复修改同一个对象。您想在for循环中创建一个新的cr实例。
答案 6 :(得分:0)
假设cr是一个类,你需要在循环的每次传递中创建一个新的类实例,比如cr = new crClassName();
原因是添加到CaseRecordItems的是指向对象的指针,而不是它的副本 - 这就是为什么当你在第二遍中更改它时第一个值似乎也会改变。