2009-06-06 10 views
1

私は過去数日間友人のために取り組んできたコードを少し持っています。高レベルでは、テキストファイルを解析してMDBに書き込みます。短いストーリーを短縮するために、私はアイテムのいくつかの処理を行うループのネストされたカップルを持っている。内部ループは、特定の場合にのみ呼び出されますが、そうである場合、それはいくつかの奇妙なことをしています。コレクションの値をforループで変更する

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); 
} 

ループは、たとえば2回実行され、cr.Tifの値をsometext_Aおよびsometext_Bに設定する必要があります。これは正しく動作しますが、コレクションに2番目のアイテムが追加されると、1番目のアイテムの値がコレクションに一致するように変更されます。

これは、これらのオブジェクトがどのようにインスタンス化されて渡されているかを私が理解していないためです。どんな洞察にも感謝します。

EDIT:素晴らしいフィードバック(と私のしびれ-nutzery)に基づいて

問題が解決されました。ダンの答えのおかげで、私はクローン機能を利用する前に試したコードにいくつかの変更を加えました(はい、私は実際にそれを試みました:P)。

新しいブロックは次のようになります。 ArrayList CaseRecordItems = new ArrayList(); //これは以前に作成されました string baseTif = "sometext_"; //これは以前に作成された 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); 
} 

超高速応答の皆様、ありがとうございます!

+0

は、我々はより完全なコードを取得することはできますか? crはどこに作られていますか? –

+0

crは、ループの直前にブロック内に作成されるポコです。 – kdmurray

+0

foreachループもありません。 –

答えて

7

私はcrがオブジェクトだとします。毎回新しいcrを作成しているわけではないので、arraylistに同じ参照が2回あるため、同じオブジェクトで実際に作業している2回目に修正します。

0

crは新しいステートメントを取得していないため(私はcrのタイプを知っていないか、またはあなたに表示します)、同じ参照を何度も繰り返しています。新しいcrアイテムをCaseRecordItemsに追加したい場合は、cr = new TypeOfCR();を実行します。それ以外の場合は、同じオブジェクトを繰り返し上書きしています。

EDIT:はあなたがオーバー、その後、あなたが同じオブジェクトを変更している、forループ内で(それが何であれ)CRを作成していない場合は、あなたのループ

0

の内側に新しい操作を行うようにしてくださいとループのたびに、繰り返します。 forループ内に新しいcrインスタンスを作成したいとします。

2

ループ内のcrインスタンスの値を変更しています。ループを通る各反復は同じインスタンスcrを使用しているため、変更するとすべてが変更されます。これを解決するために、適切な方法は、ループ内のローカルインスタンスを使用することである。

for (int i = 0; i < FirstNames.Count; i++) 
{ 
    CaseRecord cr=new CaseRecord(); 

    ... 

    CaseRecordItems.Add(cr); 
} 
+0

btw ...クラス名には良い推測。あなたは私が質問文を修正する前にそれを持っていた... hehe。 – kdmurray

1

問題が同じオブジェクトであるループを介して可変Crはループを回とも同じであるので、両方の時間同じオブジェクトがArrayListに2回追加されています。

crが宣言されている場所を示すコードを十分に表示していません。

は、クラスは、あなたがそれぞれのクラスの新しいインスタンスを作成する必要があります)(CR =新しいcrClassNameのように、ループを通過さ

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); 
} 
0

と仮定すると、CRのような何かをする必要があります。

理由は、CaseRecordItemsに追加されているのはオブジェクトへのポインタであり、オブジェクトのコピーではないということです。そのため、2番目のパスでそれを変更すると、最初の値も変更されるように見えます。

1

crオブジェクトにはクローン機能がありますか?

もしそうなら、これはそれを行う必要があります。

CaseRecordItems.Add(cr.Clone()); 
関連する問題