集合值在for循环中更改

时间:2009-06-06 04:23:07

标签: c# collections loops for-loop

我有一些代码,我过去几天一直在为朋友工作。在较高级别,它解析文本文件并写入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);
}

感谢大家的超快响应!

7 个答案:

答案 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的是指向对象的指针,而不是它的副本 - 这就是为什么当你在第二遍中更改它时第一个值似乎也会改变。