1. ホーム
  2. c#

[解決済み] C#の多次元配列と配列の配列の違いは何ですか?

2022-03-20 06:56:25

質問

多次元配列の違いは何ですか? double[,] と配列の配列(array-of-array double[][] をC#で使うか?

違いがあるとすれば、それぞれどのような使い方があるのでしょうか?

どのように解決するのですか?

配列の配列(ギザギザ配列)は多次元配列より高速で、より効果的に使用することができます。多次元配列の方が構文がきれいです。

ギザギザ配列と多次元配列を使って簡単なコードを書き、コンパイルしたアセンブリをILディスアセンブラで調べると、ギザギザ配列(または1次元配列)の格納と取り出しは単純なIL命令であるのに対し、多次元配列の同じ操作は常に低速のメソッド呼び出しであることが分かります。

次のようなメソッドを考えてみましょう。

static void SetElementAt(int[][] array, int i, int j, int value)
{
    array[i][j] = value;
}

static void SetElementAt(int[,] array, int i, int j, int value)
{
    array[i, j] = value;
}

そのILは次のようになります。

.method private hidebysig static void  SetElementAt(int32[][] 'array',
                                                    int32 i,
                                                    int32 j,
                                                    int32 'value') cil managed
{
  // Code size       7 (0x7)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  ldelem.ref
  IL_0003:  ldarg.2
  IL_0004:  ldarg.3
  IL_0005:  stelem.i4
  IL_0006:  ret
} // end of method Program::SetElementAt

.method private hidebysig static void  SetElementAt(int32[0...,0...] 'array',
                                                    int32 i,
                                                    int32 j,
                                                    int32 'value') cil managed
{
  // Code size       10 (0xa)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  ldarg.2
  IL_0003:  ldarg.3
  IL_0004:  call       instance void int32[0...,0...]::Set(int32,
                                                           int32,
                                                           int32)
  IL_0009:  ret
} // end of method Program::SetElementAt

ギザギザ配列を使用すると、行の入れ替えやサイズ変更などの操作を簡単に行うことができます。多次元配列の方が安全な場合もあるかもしれませんが、Microsoft FxCopでも、プロジェクトの分析には多次元配列ではなくギザギザ配列を使うべきであると言っています。