2

配列を使用するコードがありますが、残念ながらその型を変更できません。できれば、必要なことをするためにArrayListsまたは同様のものを使用しますが、できません。基本的に、静的配列にオブジェクトを追加および削除するための最良の方法を探しています。その場で配列に項目を追加するには、古い配列よりも 1 要素大きい新しい配列を作成し、古い配列から新しい配列に項目をコピーして、新しい項目を追加する必要があります。このようなもの...

public partial class dataStruct 
{
    private myObject[] myStaticArray;
};

private void AddItemToMyArray()
{
    int oldLength = dataStruct.myStaticArray.Length;
    myObject[] newMyObjectArray = new myObject[oldLength + 1];
    for (int i = 0; i < oldLength; i++)
       newMyObjectArray [i] = dataStruct.myStaticArray[i];

    dataStruct.myStaticArray[oldLength] = new myObject();
    dataStruct.myStaticArray = newMyObjectArray;
}

アイテムを削除するには、同じことを行いますが、アイテムが 1 つ小さい新しい配列を作成するだけです。これは本当に効率が悪いと感じます。誰かがより良いアプローチを提案できますか? または他の考えはありますか?

ご協力いただきありがとうございます。

4

6 に答える 6

6

いいえ - 配列は常に固定サイズです。それらからエントリを追加/削除することはできません。

これはまさに制限でArrayListありList<T>、効果的に回避できます。それらは内部的に配列を維持しますが、それは通常、リストの論理サイズよりも大きくなります。項目を に追加すると、List<T>可能であれば既存の配列に値が入力されます。十分なスペースがない場合は、新しいより大きな配列が作成され、その内容がコピーされます。ただし、この変更は呼び出し元には透過的です。元の参照は基になる配列ではなくリストへの参照であるため、元の参照を引き続き使用できます。

コードをより単純にする(ただし、おそらくより効率的ではない) ことの 1 つは、Array.Resizeを使用することです。既存の配列のサイズを変更するのではなく、要求したサイズで、古いコンテンツの浅いコピーを含む新しい配列を返します。コピーは手動ループよりも少し速いかもしれませんが、非効率の主な原因は依然としてそこにあります。

于 2009-03-12T16:03:04.650 に答える
3

なぜここで配列を使用したいのですか? List<T>、または(途中からの効率的な削除/挿入が必要な場合)に切り替えますLinkedList<T>

私が意味するように「静的」を意味しているかどうかはわかりません-明確にできますか?

情報については、 を使用できますがArray.Resize(ref myArray, newSize)、頻繁な変更には適切な答えではありません。

于 2009-03-12T16:02:07.553 に答える
3

残念ながら、それらのタイプを変更することはできません

なぜだめですか?唯一の合理的な答えは、API を返すかパラメーターとして要求する関数で使用する必要がある API があるということです。その場合は、必要に応じてそれまたはメソッドを使用List<T>して呼び出します。.ToArray().AddRange()

于 2009-03-12T16:24:12.960 に答える
2

その音から、データ構造を変更することはできないため、配列を処理する必要があります。

実際に助けを得ることができる唯一のことは、ループを回避して Array.copy を実行できることです

int oldLength = dataStruct.myStaticArray.Length;
myObject[] newMyObjectArray = new myObject[oldLength + 1];
Array.copy(dataStruct.myStaticArray, newMyObjectArray, oldLength);

dataStruct.myStaticArray[oldLength] = new myObject();
dataStruct.myStaticArray = newMyObjectArray;

編集実際にはこれでうまくいくかもしれません:

int oldLength = dataStruct.myStaticArray.Length;
Array.Resize(dataStruct.myStaticArray, oldLength+1);
于 2009-03-12T16:09:01.360 に答える
0

あなたは基本的に独自のリストを書いていますが、効率の悪い方法です。

List は、あなたが説明していることを内部的に行いますが、パフォーマンスに関して大きな違いが 1 つあります。

内部配列を再割り当てするとき、新しい要素を 1 つ追加するだけでなく、それらのブロックを追加します。そうすれば、将来の追加で常に再割り当てが必要になるわけではありません。これがリストの「容量」です。リストの容量が常に >= リストのサイズである理由です。

これを行う必要がある場合は、同様のことをお勧めします。ただし、リストに切り替える方がはるかに優れたオプションです。

于 2009-03-12T16:04:17.283 に答える
0

配列をArrayListorのようにするためにできることはList<T>すべて、それらのクラスの一部 (またはすべて) を再実装することになります。他の回答が述べているように、組み込みクラスを使用するのが最善です。

于 2009-03-12T16:05:05.767 に答える