1

配列を次のように初期化しました

Double[][] myarr = Enumerable.Repeat(new double[12], 13).ToArray();

次に、ループで次のような値をインクリメントしています

myarr[0][0]++; 

これにより、myarr [1] [0]、myarr [2] [0]、myarr [3] [0] ..... myarr[12][0]などのすべての値が1つインクリメントされます。

この問題は、forループ(0〜12)を使用している場合は発生しません。

myarr[i] = new double[12];

なんでそうなの?

4

6 に答える 6

5

他の答えが問題を説明しています。解決策は、反復ごとに新しい配列を作成することです。

double[][] myarr = Enumerable.Range(0, 13)
                             .Select(ignored => new double[12])
                             .ToArray();
于 2012-04-09T09:08:54.323 に答える
2

new double[12]doubleの配列への参照を作成し、その参照を12回繰り返すと、 myarr [0..n]は1つのメモリ領域を参照します。

次の方法を使用して、問題を解決できます

static T[][] CreateArray<T>(int rows, int cols)
{
    T[][] array = new T[rows][];
    for (int i = 0; i < array.GetLength(0); i++)
        array[i] = new T[cols];

    return array;
}

または、ステップごとにアクションを呼び出すカスタムのRepeatメソッドを使用します。

public static IEnumerable<TResult> RepeatAction<TResult>(Action<TResult> elementAction, int count)
{
    for (int i = 0; i < count; i++)
    {
        yield return elementAction();
    }
    yield break;
}
usage
RepeatAction(()=>new double[12], 12);
于 2012-04-09T09:05:21.740 に答える
2

これnew double[12]は、メモリ内に単一の配列オブジェクトを作成するためです。Enumerable.Repeatは、その配列への複数の参照を提供するだけです。

于 2012-04-09T09:06:03.593 に答える
2

これは予想される動作です。配列は参照型です。ギザギザの配列、つまり配列の配列を作成しています。外側の配列のすべての要素は同じ内側の配列、つまりRepeat呼び出しの最初の引数を参照するため、内側の配列の変更はインデックスに反映されます(すべてのインデックスが同じ配列を参照するため)。

于 2012-04-09T09:07:04.650 に答える
1

配列は参照です。呼び出しでは、Repeat1つの配列を作成し、その参照を12回割り当てます。ただし、ループでは、12個の異なる配列を作成します。

于 2012-04-09T09:05:13.650 に答える
1

Repeat()基本的には、同じ要素を複数回キャプチャして生成するだけなので、メモリ内の同じオブジェクトインスタンスへの複数の参照を取得します。

Repeat()実装方法は次のとおりです。

private static IEnumerable<TResult> RepeatIterator<TResult>(TResult element, int count)
{
    for (int i = 0; i < count; i++)
    {
        yield return element;
    }
    yield break;
}
于 2012-04-09T09:06:51.903 に答える