0

.xls ファイルからデータをロードする既知のライブラリがあり、Excel ワークブックの最初のシートのデータが入力された DataTable を返すとします。また、デバッガーが動作していないときにメッセージを出力するログ機能。

DataTable dtFoo = null;
DataTable dtBar = null;
DataTable dtChaz = null;

String[] files = new String[]{ "file1.xls", "file2.xls", "file2.xls" };
DataTable[] dts = new DataTable[] { dtFoo, dtBar, dtChaz };

for(int i = 0; i < 3; i++)
{
    dts[i] = SomeLibrary.LoadFromFile(files[i]); //Returns a new DataTable
    Log((dts[i] == null) + " " + dts[i].Rows.Count)
}

Log((dts[0] == null) + " " + (dtFoo == null));
Log((dts[1] == null) + " " + (dtBar == null));
Log((dts[2] == null) + " " + (dtChaz == null));

Log Output:

  False 40
  False 455
  False 34
  False True
  False True
  False True

明らかに、参照型変数を操作するときに、理解できなかった重要な何かが欠けています。ループが完了した後でも DataTable 変数が null のままなのはなぜですか?

4

3 に答える 3

7

この行:

DataTable[] dts = new DataTable[] { dtFoo, dtBar, dtChaz };

...あなたが考えているように、変数を配列要素でエイリアスしません。新しい配列を作成し、初期を 、 、 の値にdtFooそれぞれdtBar設定しdtChazます (これらはすべて null です)。その後、配列と変数は完全に分離されます。

後で変数を設定する場合は、次のものが必要です。

dtFoo = dts[0];
dtBar = dts[1];
dtChaz = dts[2];

もちろん、これはDataTables である必要はありません。簡単な例:

string x = "initial";
string[] array = new string[] { x };
array[0] = "modified";

Console.WriteLine(x); // "initial"
x = array[0];
Console.WriteLine(x); // "modified"

これは、配列要素の値を変更する場合であることに注意してください。代わりに、値が参照するオブジェクトを変更する場合、それは別の問題です:

StringBuilder builder = new StringBuilder("123");
StringBuilder[] array = new StringBuilder[] { builder };
builder[0].Append("456");
Console.WriteLine(builder); // 123456

詳細については、参照型と値型に関する私の記事を参照してください。基本的に、参照と参照先のオブジェクトを区別する必要があります。

于 2013-01-15T19:28:57.727 に答える
2

試したコードの代わりにできる提案として

DataSet ds = new DataSet();
ds.Tables.Add(dtFoo);
ds.Tables.Add(dtBar);
ds.Tables.Add(dtChaz );

データテーブルの配列を作成する代わりに、データセットにテーブルを追加しました

変更されたコードは

DataSet ds = new DataSet();
for(int i = 0; i < 3; i++)
{
    ds.Tables.Add(SomeLibrary.LoadFromFile(files[i])); //Returns a new DataTable
}
于 2013-01-15T19:30:22.680 に答える
1

行を追加する必要があります

dtFoo = dts[0];
dtBar = dts[1];
dtChaz = dts[2];

ログ行の前。

init ステートメントは代入ステートメントには影響しません。

于 2013-01-15T19:32:37.000 に答える