C#のArrayList
とList<>
の違いは何ですか?
List<>
が型を持つ一方でArrayList
が型を持たないということだけですか?
はい、ほとんどです。 List<T>
はジェネリッククラスです。 object
との間でキャストしたりキャストしたりせずに特定の型の値を格納することをサポートします(T
がArrayList
の場合の値型である場合、ボックス化/ボックス化解除のオーバーヘッドが発生します)。 ArrayList
は単にobject
参照を格納するだけです。総称コレクションとして、List<T>
は総称IEnumerable<T>
インターフェースを実装し、LINQで簡単に使用できます(Cast
またはOfType
呼び出しを必要とせずに)。
ArrayList
はC#が総称を持たなかった時代に属します。 List<T>
のために廃止予定です。 .NET> = 2.0をターゲットとする新しいコードでは、それを使用する古いAPIとのインタフェースが必要でない限り、ArrayList
を使用しないでください。
List<T>
を使用すると、キャストエラーを防ぐことができます。 runtime キャストエラーを回避するのは非常に便利です。
例:
ここで(ArrayList
を使用して)このコードをコンパイルできますが、後で実行エラーが発生します。
ArrayList array1 = new ArrayList();
array1.Add(1);
array1.Add("Pony"); //No error at compile process
int total = 0;
foreach (int num in array1)
{
total += num; //-->Runtime Error
}
List
を使用すれば、これらのエラーを回避できます。
List<int> list1 = new List<int>();
list1.Add(1);
//list1.Add("Pony"); //<-- Error at compile process
int total = 0;
foreach (int num in list1 )
{
total += num;
}
参照先: _ msdn _
上記の点に追加します。 64ビットオペレーティングシステムでArrayList
を使用すると、32ビットオペレーティングシステムで使用するよりも2倍のメモリが消費されます。一方、総称リストList<T>
はArrayList
よりもはるかに少ないメモリを使用します。
たとえば、32ビットで19MBのArrayList
を使用すると、64ビットでは39MBかかります。しかし、32ビットで8MBの汎用リストList<int>
があるとすれば、64ビットでは8.1MBしかかからず、これはArrayListと比較したときに481%の大きな違いです。
追加すべきもう1つの違いは、スレッド同期に関する点です。
ArrayList
はSynchronizedプロパティを通してスレッドセーフを提供します。これはコレクションの周りのスレッドセーフラッパーを返します。ラッパーは、追加または削除操作のたびにコレクション全体をロックすることによって機能します。したがって、コレクションにアクセスしようとしている各スレッドは、順番が1つロックされるのを待つ必要があります。これはスケーラブルではなく、大規模コレクションではパフォーマンスが大幅に低下する可能性があります。
List<T>
はスレッド同期を提供しません。項目が複数のスレッドで同時に追加または削除された場合、ユーザーコードはすべての同期を提供する必要があります。
より詳しい情報はこちら .NET Frameworkにおけるスレッド同期
簡単な答えは
ArrayList arrayList = new ArrayList();
List<int> list = new List<int>();
arrayList.Add(1);
arrayList.Add("String");
arrayList.Add(new object());
list.Add(1);
list.Add("String"); // Compile-time Error
list.Add(new object()); // Compile-time Error
マイクロソフトの公式ドキュメントをお読みください : https://blogs.msdn.Microsoft.com/ja-jp/kcwalina/2005/09/23/system-collections-vs-system-collection-generic-and-system -collections-objectmodel/
注 :違いを理解する前にGenericsを知っておく必要があります。 https://docs.Microsoft.com/ja-jp/dotnet/csharp/programming-guide/generics/
ArrayList
は型保証されていませんが、List<T>
は型保証されています。シンプル:)。
ArrayList
はさまざまな型のデータのコレクションですが、List<>
はそれ自体が依存する類似した型のコレクションです。
ArrayList
とList<T>
の違いは次のとおりです。
List<T>
、ここでTはvalue-typeです。ArrayList
より速いです。これはList<T>
がボックス化/ボックス化解除を回避するためです(Tは値型)。ArrayList
は後方互換性のためだけに使用されます。 (それは本当の違いではありませんが、私はそれが重要な注意であると思います)。ArrayList
、List<T>
の方が反射が簡単ですArrayList
はIsSynchronized
プロパティを持ちます。そのため、同期化されたArrayList
を作成して使用するのは簡単です。 List<T>
のIsSynchronized
プロパティが見つかりませんでした。また、この種の同期は比較的非効率的です( msdn )。
var arraylist = new ArrayList();
var arrayListSyncronized = ArrayList.Synchronized(arraylist
Console.WriteLine($"syncronized {arraylist.IsSynchronized}");
Console.WriteLine($"syncronized {arrayListSyncronized.IsSynchronized}");
var list = new List<object>();
var listSyncronized = ArrayList.Synchronized(list);
Console.WriteLine($"syncronized {list.IsSynchronized}");//error, no such prop
Console.WriteLine($"syncronized {list.IsSynchronized}");//error, no such prop
ArrayList
には、同期に使用できるArrayList.SyncRoot
プロパティがあります( msdn )。 List<T>
はSyncRoot
プロパティを持っていません。そのため、List<T>
を使用する場合は、次の構成で何らかのオブジェクトを使用する必要があります。
ArrayList myCollection = new ArrayList();
lock(myCollection.SyncRoot) // ofcourse you can use another object for this goal
{
foreach (object item in myCollection)
{
// ...
}
}