8

SOに関する別の質問について話し合っているときに、構文が

int[] numbers = new int[10];

よりも良い

Array numbers = Array.CreateInstance(typeof(int), 10);

私の質問は、最初の構文が役立つのはいつで、2 番目の構文が役立つのはいつですか? なぜ?

4

4 に答える 4

8

これにより、強く型付けされた一次元配列が「直接」作成されます。

int[] array = new int[10];

内部では、ILコマンドを使用しnewarrます。

これは、リフレクションを使用して配列を作成することに似ています(タイプは実行時に決定できます)

int[] array2 = (int[])Array.CreateInstance(typeof(int), 10);

最終的に作成される配列は同じですが、を使用すると作成速度が大幅に低下しArray.CreateInstanceます。Array.CreateInstanceを使用すると、配列のタイプを動的に選択できることに注意してください(リフレクションを使用して、実行時にタイプを指定してタイプのインスタンスを作成できるのと同じ方法で)。次に例を示します。

Type type = someCondition ? typeof(int) : typeof(string);
Array array2 = Array.CreateInstance(type, 10);

もう1つの大きな違いは、「基本」Arrayクラスの型が弱いことです(したがって、そのメソッドは/ '/のobject代わりにパラメーターを使用します)。それで:intstringsomething

int num = (int)array2.GetValue(1); // You have to cast the return value to int from object

使用するもう1つの理由

array[5] = 1;

それ以外の

array2.SetValue(5, 1);

最初の方法は、一次元配列(stelemおよびldelem)への直接アクセスとしてILコードで最適化されているということです。同じことが。にも当てはまりますGetValue


「一次元配列」という用語を使用している理由:

.NETには、2つの「タイプ」の配列があります。1次元配列と「複雑な」配列です(多次元であるか、最初の要素が0インデックスにないか、またはその両方である可能性があります)。2番目のグループははるかに遅いです。およびはstelemldelem一次元配列でのみ機能します。多次元/特殊配列の場合、「非表示」メソッドを使用してアクセスします(C#コンパイラは、これらのメソッドが呼び出されるようにgetとsetを変更します)(これらはクラスのGetValue/SetValueに似ています。Arrayたとえば、https://stackoverflowを参照してください。 com / a / 597729/613130

于 2013-02-20T13:09:02.357 に答える
5

コンパイル時に、それらの間に大きな違いはないように見えます。配列と同様に、Array.CreateInstanceメソッドも参照型要素を に初期化しnullます。値型要素は に初期化されzeroます。

ここに画像の説明を入力

2 つ目の違いは次のとおりです。MSDNから;

ほとんどのクラスとは異なり、Array はパブリック コンストラクターの代わりに CreateInstance メソッドを提供し、レイト バインド アクセスを可能にします。

また、Stefano Altieriが述べたように、最初の構文ではコンパイル時に配列サイズが必要ですが、2 番目の構文では実行時にサイズが必要です。たとえば、これらのコードを正常にビルドできます。

int[] numbers1 = new int[10];
Array numbers2 = Array.CreateInstance(typeof(int), -1);

しかし、これらを構築することはできません。

int[] numbers1 = new int[];
Array numbers2 = Array.CreateInstance(typeof(int), -1);
于 2013-02-20T13:01:30.577 に答える
4

あなたが書いたサンプルは同等です。重要なのは、最初の構文(new int [size])を使用するには、コンパイル時に配列型を知る必要があるということです。

2番目の構文では、実行時に配列項目のタイプを決定できます。これははるかに強力ですが、常にこの力が必要なわけではありません。つまり

Type myType = SelectTheBestType();
var numbers = Array.CreateInstance(myType, 10);
于 2013-02-20T13:07:05.593 に答える
2

ソネル・ギョニュルの答えはかなり良いです。あなたの質問の簡単な理由は

配列がオブジェクトまたはインターフェイスとして渡される場合、コンパイル時に要素タイプは不明です。

[この答え]はあなたにアイデアをもたらすかもしれません、そして[ここ]は例えばいくつかのコードです。

最初の構文はいつ有用で、2番目の構文はいつ有用ですか?

例のリンクのメソッド、

static IList CreateArray<T>(this T source);

ジェネリック型パラメーターは、必ずしも配列であるとは言えないためではありませんTが、それでも可能性があります。したがって、メソッド内でのみ使用できます。T[]source Array.CreateInstance

ほとんどの場合、コンパイル時に要素タイプがすでにわかっている場合は、言語によって提供される構文を使用することをお勧めします。

于 2013-02-20T14:07:50.927 に答える