これは、C#の特に紛らわしい機能です。これが取引です。
この説明全体を通して、配列の要素型は値型ではなく参照型であると想定しています。
C#は、安全でない配列共分散をサポートしています。つまり、文字列の配列がある場合、文字列をオブジェクトに変換できるため、それをオブジェクトの配列に変換できます。
string[] a1 = { "hello", "goodbye" };
object[] a2 = a1; // Legal
次に、a2から要素を取得しようとすると、次のように機能します。
object o3 = a2[0];
a2[0]
は実際a1[0]
には、オブジェクトに変換可能な文字列であるため、これは合法です。
ただし、配列に書き込もうとすると、実行時にエラーが発生します。
a2[0] = new object();
a2
は実際には文字列の配列であり、文字列以外の文字列を文字列の配列に入れることはできないため、これは実行時に失敗します。
したがって、C#はすでにひどく壊れています。コンパイルして正常に見えるプログラムを作成することは可能ですが、実際にはオブジェクトの配列ではないオブジェクトの配列にオブジェクトを配置しようとしたため、実行時に型例外で突然クラッシュします。
必要な機能はそれよりもさらに壊れており、C#はそれをサポートしていません。必要な機能は次のとおりです。
object[] a4 = { "Hello" };
string[] a5 = a4;
それは安全でない配列の共変性です。それはこのようにひどく壊れます:
a4[0] = new Customer(); // Perfectly legal
string s6 = a5[0];
そして今、Customerをstring型の変数にコピーしました。
いかなる種類の配列共分散または反変性も避ける必要があります。あなたが発見したように、配列の共変性は合法ではなく、配列の共分散はあなたのプログラムで予期せずに消える小さな時限爆弾を作っています。まず、適切なタイプの配列を作成します。