代码之家  ›  专栏  ›  技术社区  ›  kdmurray

在for循环中更改的集合值

  •  1
  • kdmurray  · 技术社区  · 15 年前

    在过去的几天里,我一直在为一个朋友编写一些代码。在高层,它解析文本文件并写入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。这工作正常,但一旦将第二个项添加到集合中,第一个项的值将更改为与之匹配。

    我怀疑这是由于我不理解这些对象是如何被实例化和传递的。任何见解都会受到赞赏。

    编辑:

    基于可怕的反馈(和我麻木的疯子),问题已经解决。由于丹的回答,我对使用克隆函数之前尝试过的代码做了一些更改(是的,Beach实际上尝试过:p)。

    新块如下所示: arraylist caseRecorditems=new arraylist();//这是前面创建的 string basetif=“sometext_u”;//这是前面创建的 caseRecord cr=new caseRecord();//用“stuff”填充) 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 回复  |  直到 15 年前
        1
  •  7
  •   Dan Fuller    15 年前

    我假设cr是一个对象。您不会每次都创建一个新的CR,所以在ArrayList中有两次相同的引用,因此当您第二次修改它时,实际上是在处理同一个对象。

        2
  •  2
  •   1800 INFORMATION    15 年前

    您正在更改 cr 循环内的实例。通过循环的每个迭代使用的是 所以当你改变它时,它们都会改变。要解决此问题,适当的方法是在循环内使用本地实例:

    for (int i = 0; i < FirstNames.Count; i++)
    {
        CaseRecord cr=new CaseRecord();
    
        ...
    
        CaseRecordItems.Add(cr);
    }
    
        3
  •  1
  •   David Norman    15 年前

    问题是变量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);
    }
    
        4
  •  1
  •   beach    15 年前

    CR对象有克隆函数吗?

    如果是这样,应该这样做:

    CaseRecordItems.Add(cr.Clone());
    
        5
  •  0
  •   Greg    15 年前

    因为cr没有得到一个新的语句(我不知道cr的类型,或者我会向您展示),所以您只是不断地添加相同的引用。如果要向caseRecordItems添加新的cr项,则需要执行cr=new typeofcr();否则,您只是一次又一次地重写同一对象。

    编辑: 一定要在你的循环里做新的

        6
  •  0
  •   Michael Petrotta user3140870    15 年前

    如果您没有在for循环中创建cr(无论它是什么),那么每次在循环中都要反复修改同一个对象。您希望在for循环内创建一个新的CR实例。

        7
  •  0
  •   Bob    15 年前

    假设cr是一个类,您将需要在每次通过循环时创建该类的新实例,比如cr=new crclassname();

    原因是,添加到caseRecordItems中的是指向对象的指针,而不是对象的副本——这就是为什么当您在第二次传递时更改它时,第一个值似乎也会更改。