13

おそらく奇妙なことですが、.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;

これは問題なく動作します。

4

5 に答える 5

3

片方からもう一方にキャストできないのは、これが悪だからです。

object[5..9] の配列を作成し、それを関数 F に object[] として渡すとします。

関数はこれが 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();
    }

}
于 2008-09-11T13:09:40.180 に答える
1

なぜそれをObject[]として渡せないのかはわかりませんが、配列をラップしてそこで「奇妙なロジック」を処理する実際のクラスを作成するだけでは簡単ではないでしょうか。

クラスに「インテリジェンス」を追加できれば、実際の参照オブジェクトを使用するメリットが得られます。

編集:配列をどのようにキャストしていますか?さらにコードを投稿できますか?ありがとう。

于 2008-09-11T12:48:43.443 に答える
1

下限を const オフセット整数に格納し、ソースがインデックスとして返すものからその値を差し引くだけです。

また、これは古い VB6 機能です。それをサポートするのに役立つ属性があるかもしれないと思います。

于 2008-09-11T13:32:36.147 に答える
0

.NET CLR は、 SZ 配列MZ 配列の 2 つの内部配列オブジェクト形式を区別します。MZ 配列は多次元にすることができ、その下限をオブジェクトに格納できます。

この違いの理由は 2 つあります。

  1. 1 次元配列の効率的なコード生成には、下限がないことが必要です。下限を持つことは非常にまれです。このめったに使用されない機能のために、一般的なケースでパフォーマンスを大幅に犠牲にしたくはありません。
  2. ほとんどのコードは、下限がゼロの配列を想定しています。下限をチェックしたり、ループの境界を調整したりして、すべてのコードを汚染したくはありません。

これらの問題は、SZ 配列に別の CLR 型を作成することで解決されます。これは、実際に発生するほぼすべての配列が使用している型です。

于 2021-09-07T04:56:06.630 に答える