5

任意のランクの配列を反復処理する必要があります。これは読み取りと書き込みの両方に使用されるため、機能しGetEnumeratorません。

Array.SetValue(object, int)多次元配列では機能しません。 Array.SetValue(object, params int[])多次元空間を反復処理するには、過度の演算が必要になります。paramsまた、署名の一部を回避するために動的な呼び出しが必要になります。

配列を固定してポインターで反復したいのですが、多次元配列が連続していることが保証されているというドキュメントは見つかりません。ディメンションの最後にパディングがある場合、それは機能しません。また、安全でないコードは避けたいと思います。

単一のインデックスのみを使用して多次元配列を順番にアドレス指定する簡単な方法はありますか?

4

3 に答える 3

5

多次元配列は連続していることが保証されています。ECMA-335から:

配列要素は、配列オブジェクト内で行優先の順序で配置される必要があります(つまり、右端の配列次元に関連付けられた要素は、最低から最高のインデックスまで連続して配置される必要があります)。

したがって、これは機能します。

int[,,,] array = new int[10, 10, 10, 10];

fixed (int* ptr = array)
{
    ptr[10] = 42;
}

int result = array[0, 0, 1, 0];  // == 42
于 2010-08-04T18:52:42.877 に答える
1

Rankandプロパティ/メソッドを使用して、配列とメソッドGetUpperBoundに渡すことができるインデックス配列を作成できます。SetValueGetValue

int[] Indices(Array a, int idx)
{
    var indices = new int[a.Rank];

    for (var i = 0; i < a.Rank; i++)
    {
        var div = 1;

        for (var j = i + 1; j < a.Rank; j++)
        {
            div *= a.GetLength(j);
        }

        indices[i] = a.GetLowerBound(i) + idx / div % a.GetLength(i);
    }

    return indices;
}

..そしてそれを次のように使用します:

for (var i = 0; i < array.Length; i++)
{
    var indices = Indices(array, i);
    array.SetValue(i, indices);
    var val = array.GetValue(indices);
}
于 2010-08-04T19:31:26.153 に答える
-1

おそらく、それらすべてを1つの一時的なコレクションに結合して、それを繰り返すことができます。

于 2010-08-04T18:50:12.727 に答える