宣言後に配列サイズを変更することは可能ですか?そうでない場合、配列に代わるものはありますか?
サイズ1000の配列を作成したくありませんが、作成するときに配列のサイズがわかりません。
いいえ、代わりに厳密に型指定された List を使用してみてください。
例えば:
代わりに
int[] myArray = new int[2];
myArray[0] = 1;
myArray[1] = 2;
これを行うことができます:
List<int> myList = new List<int>();
myList.Add(1);
myList.Add(2);
リストは配列を使用してデータを保存するので、手動ですることを心配せずに項目を追加および削除できるため、LinkedList
の便利さで配列の速度の利点が得られますサイズを変更します。
これは、配列のサイズ(この場合はList
)が変更されないことを意味しません-したがって、Wordを手動で強調します。
配列が定義済みのサイズに達するとすぐに、JITはヒープの2倍のサイズの新しい配列を割り当て、既存の配列をコピーします。
[〜#〜] msdn [〜#〜] に記載されているArray.Resize()
を使用できます。
しかし、そうです、動的なサイズのデータ構造が必要な場合、List
sがあります。
重要:Array.Resize()
配列のサイズを変更しません(メソッド名は誤解を招く)、新しい配列を作成し、 参照 メソッドに渡しました。
例:
var array1 = new byte[10];
var array2 = array1;
Array.Resize<byte>(ref array1, 20);
// Now:
// array1.Length is 20
// array2.Length is 10
// Two different arrays.
.net 3.5以降ではArray.Resize()
を使用できます。このメソッドは、指定されたサイズの新しい配列を割り当て、古い配列から新しい配列に要素をコピーし、古い配列を新しい配列に置き換えます。 (したがって、これはおそらくカバーの下でArray.Copy
を使用するため、両方のアレイで使用可能なメモリが必要になります)
使う List<T>
代わりに。たとえば、intの配列の代わりに
private int[] _myIntegers = new int[1000];
つかいます
private List<int> _myIntegers = new List<int>();
後
_myIntegers.Add(1);
C#では、配列のサイズを動的に変更することはできません。
1つのアプローチは、System.Collections.ArrayList
の代わりにnative array
。
別の(より高速な)ソリューションは、異なるサイズの配列を再割り当てし、古い配列の内容を新しい配列にコピーすることです。
汎用関数resizeArray
(以下)を使用してこれを行うことができます。
public static System.Array ResizeArray (System.Array oldArray, int newSize)
{
int oldSize = oldArray.Length;
System.Type elementType = oldArray.GetType().GetElementType();
System.Array newArray = System.Array.CreateInstance(elementType,newSize);
int preserveLength = System.Math.Min(oldSize,newSize);
if (preserveLength > 0)
System.Array.Copy (oldArray,newArray,preserveLength);
return newArray;
}
public static void Main ()
{
int[] a = {1,2,3};
a = (int[])ResizeArray(a,5);
a[3] = 4;
a[4] = 5;
for (int i=0; i<a.Length; i++)
System.Console.WriteLine (a[i]);
}
バイトの配列にこのアプローチを使用しました:
最初は:
byte[] bytes = new byte[0];
必要なときはいつでも(延長のために元の長さを提供する必要があります):
Array.Resize<byte>(ref bytes, bytes.Length + requiredSize);
リセット:
Array.Resize<byte>(ref bytes, 0);
型付きリスト方式
最初は:
List<byte> bytes = new List<byte>();
必要なときはいつでも:
bytes.AddRange(new byte[length]);
リリース/クリア:
bytes.Clear()
はい、配列のサイズを変更できます。例えば:
int[] arr = new int[5];
// increase size to 10
Array.Resize(ref arr, 10);
// decrease size to 3
Array.Resize(ref arr, 3);
CreateInstance()メソッドで配列を作成する場合、Resize()メソッドは機能しません。例えば:
// create an integer array with size of 5
var arr = Array.CreateInstance(typeof(int), 5);
// this not work
Array.Resize(ref arr, 10);
配列のサイズは動的ではなく、サイズを変更することもできます。動的配列が必要な場合は、代わりに汎用リストを使用できると思います。
var list = new List<int>();
// add any item to the list
list.Add(5);
list.Add(8);
list.Add(12);
// we can remove it easily as well
list.Remove(5);
foreach(var item in list)
{
Console.WriteLine(item);
}
C#では、Array.Resize
は、配列を新しいサイズに変更する最も簡単な方法です。例:
Array.Resize<LinkButton>(ref area, size);
ここで、LinkButton配列の配列サイズを変更します。
<LinkButton>
=配列タイプを指定しますref area
= refはキーワードで、 'area'は配列名ですsize
=新しいサイズの配列
private void HandleResizeArray()
{
int[] aa = new int[2];
aa[0] = 0;
aa[1] = 1;
aa = MyResizeArray(aa);
aa = MyResizeArray(aa);
}
private int[] MyResizeArray(int[] aa)
{
Array.Resize(ref aa, aa.GetUpperBound(0) + 2);
aa[aa.GetUpperBound(0)] = aa.GetUpperBound(0);
return aa;
}
配列のサイズ変更にはコストがかかるため、データを追加/削除する場合はリスト(Tは任意の型またはオブジェクト)を使用します。 やや有害と考えられる配列 について詳しく読むことができますが、リストは新しいレコードに追加でき、最後に追加できます。必要に応じてサイズを調整します。
リストは次の方法で初期化できます
コレクション初期化子を使用します。
List<string> list1 = new List<string>()
{
"carrot",
"fox",
"Explorer"
};
コレクション初期化子でvarキーワードを使用します。
var list2 = new List<string>()
{
"carrot",
"fox",
"Explorer"
};
パラメータとして新しい配列を使用します。
string[] array = { "carrot", "fox", "Explorer" };
List<string> list3 = new List<string>(array);
コンストラクターで容量を使用して割り当てます。
List<string> list4 = new List<string>(3);
list4.Add(null); // Add empty references. (Not Recommended)
list4.Add(null);
list4.Add(null);
list4[0] = "carrot"; // Assign those references.
list4[1] = "fox";
list4[2] = "Explorer";
各要素にAddメソッドを使用します。
List<string> list5 = new List<string>();
list5.Add("carrot");
list5.Add("fox");
list5.Add("Explorer");
したがって、オブジェクトリストの場合、リストの初期化とインラインでオブジェクトのプロパティを割り当てて割り当てることができます。オブジェクト初期化子とコレクション初期化子は、同様の構文を共有しています。
class Test
{
public int A { get; set; }
public string B { get; set; }
}
コレクション初期化子でリストを初期化します。
List<Test> list1 = new List<Test>()
{
new Test(){ A = 1, B = "Jessica"},
new Test(){ A = 2, B = "Mandy"}
};
新しいオブジェクトでリストを初期化します。
List<Test> list2 = new List<Test>();
list2.Add(new Test() { A = 3, B = "Sarah" });
list2.Add(new Test() { A = 4, B = "Melanie" });
Array.Reset
(変数がローカルではない)を使用できない場合、Concat
&ToArray
が役立ちます:
anObject.anArray.Concat(new string[] { newArrayItem }).ToArray();
これは、クラス配列から動的配列を作成するのに役立ちました。
var s = 0;
var songWriters = new SongWriterDetails[1];
foreach (var contributor in Contributors)
{
Array.Resize(ref songWriters, s++);
songWriters[s] = new SongWriterDetails();
songWriters[s].DisplayName = contributor.Name;
songWriters[s].PartyId = contributor.Id;
s++;
}
本当に配列に戻す必要がある場合は、array
をlist
に変換するのが最も簡単で、リストを展開してからarray
に戻すのが最も簡単です。
string[] myArray = new string[1] {"Element One"};
// Convert it to a list
List<string> resizeList = myArray.ToList();
// Add some elements
resizeList.Add("Element Two");
// Back to an array
myArray = resizeList.ToArray();
// myArray has grown to two elements.