質問
おそらく奇妙なことですが、.Net で下限 > 0 の配列を作成する必要があります。これは、次のものを使用すると、最初は可能であるように見えます。
Array.CreateInstance(typeof(Object), new int[] {2}, new int[] {9});
望ましい結果 (下限が 9 に設定されたオブジェクトの配列) が生成されます。ただし、作成された配列インスタンスは、期待されている他のメソッドに渡すことはできなくなります。 Object[]
次のようなエラーが表示されます:
System.Object[*]
にキャストすることはできません System.Object[]
. 。配列型のこの違いは何ですか?これを克服するにはどうすればよいですか?
編集:テストコード =
Object x = Array.CreateInstance(typeof(Object), new int[] {2}, new int[] {9});
Object[] y = (Object[])x;
これは次のように失敗します。「'System.Object[*]' 型のオブジェクトを 'System.Object[]' 型にキャストできません。」
このアプローチにも注目したいと思います あります 複数のディメンションを使用する場合に機能します。
Object x = Array.CreateInstance(typeof(Object), new int[] {2,2}, new int[] {9,9});
Object[,] y = (Object[,])x;
それはうまくいきます。
他のヒント
一方からもう一方へキャストできない理由は、これが悪であるからです。
object[5..9] の配列を作成し、それを object[] として関数 F に渡すとします。
関数はこれが 5..9 であることをどのようにして知るのでしょうか?F は一般的な配列を期待していますが、制約された配列を取得しています。それを知ることは可能だと言えますが、それでもこれは予期せぬことであり、単純な配列を使用するたびにあらゆる種類の境界チェックを行いたくありません。
配列はプログラミングにおいて最も単純な構造であるため、複雑すぎると使用できなくなります。おそらく別の構造が必要になります。
できるのは、必要な動作を模倣する制約付きコレクションであるクラスです。こうすることで、そのクラスのすべてのユーザーが何を期待するかを知ることができます。
class ConstrainedArray<T> : IEnumerable<T> where T : new()
{
public ConstrainedArray(int min, int max)
{
array = new T[max - min];
}
public T this [int index]
{
get { return array[index - Min]; }
set { array[index - Min] = value; }
}
public int Min {get; private set;}
public int Max {get; private set;}
T[] array;
public IEnumerator<T> GetEnumerator()
{
return array.GetEnumarator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return array.GetEnumarator();
}
}
これを Object[] として渡せない理由はわかりませんが、実際のクラスを作成して配列をラップし、そこで「奇妙なロジック」を処理するだけなら簡単ではないでしょうか。
実際の参照オブジェクトを使用すると、クラスに「インテリジェンス」を追加できるという利点が得られます。
編集:配列をどのようにキャストしていますか。さらにコードを投稿していただけますか?ありがとう。
下限を const offset 整数に格納し、ソースがインデックスとして返す値からその値を減算するだけです。
また:これは古い VB6 の機能です。それをサポートする属性があるのではないかと思います。