web-dev-qa-db-ja.com

C#でarray []に対してArrayListを使用する場合

私はよく '通常の' array[]の代わりにArrayListを使用します。

ArrayListを使用すると、不正行為をしている(または怠惰になっている)ように感じますが、配列に対してArrayListを使用しても大丈夫ですか?

37
inspite

配列は強く型付けされており、パラメーターとして適切に機能します。コレクションの長さがわかっていて、それが固定されている場合は、配列を使用する必要があります。

ArrayListは強く型付けされていません。すべての挿入または再試行では、元の型に戻すためにキャストが必要になります。特定の型のリストを取得するメソッドが必要な場合、任意の型を含むArrayListを渡すことができるため、ArrayListは不十分です。 ArrayListsは、動的に拡張する配列を内部で使用するため、容量に達したときに内部配列のサイズを拡張するヒットもあります。

本当に使いたいのは、List<T>のような一般的なリストです。これには、ArrayとArrayListsのすべての利点があります。強く型付けされており、可変長のアイテムをサポートします。

63
Bob

ボブとフレデリックの応答に加えて、配列には共分散がありますが、ジェネリックリストにはないことを指摘したいと思います。たとえば、タイプMyChildClass[]の配列はMyParentClass[]に簡単にキャストできますが、List<MyChildClass>は少なくとも直接ではなくList<MyParentClass>にキャストできません。

共分散が必要な場合は、配列を使用するか、LINQのCast()メソッドを使用するか、その他の方法を使用して各アイテムを個別にキャストします。 またはC#4を待つ

14
Tamas Czinege

ここでのもう1つの考えは、突然変異です。配列(T[])は完全に変更可能であり、保護することはできません。 List<T>は有用な拡張ポイントを提供しませんが、Collection<T>(または他の多くのIList<T>実装)のようなものを使用すると、コードを追加できます。たとえば、アイテムを追加する前にチェックできます。同様に、読み取り専用のIList<T>実装を使用できます。これは、不変性が望ましいスレッドセーフに役立ちます。

私は配列を内部メソッドロジック(おそらくローカル変数として)、params引数として、またはアイテムの長さを知っていてコードを知っているいくつかの高度に最適化されたケースで使用する傾向があります- 選択(プライベートフィールドとして)変更しないでください。それ以外は、List<T>などは、アイテムを追加/削除するときのオーバーヘッドがはるかに少ないため、より一般的である傾向があります。

7
Marc Gravell

コードのその部分が絶対にパフォーマンスクリティカルでない限り、ArrayListの使用はまったく問題ありません。

5

さらに良いことに、ArrayListを使用する場合は常に、代わりにList<T>ジェネリックコレクションを使用してください。前者より強く型付けされています。

4

私はこれにJavaの観点から答えていますが、これは同じ基本的な問題です。より高い抽象化を使用しても罪悪感を感じることはありません。結局のところ、char[]の代わりにStringsを使用しています。 、またはbyte[]?さらに一歩進んで、可能な場合はListインターフェイスを使用することをお勧めします。一歩下がる唯一の理由は、パフォーマンス上の理由です。

より高いコレクションの抽象化を使用すると、多くの利点があります。デコレータを追加して、リストを読み取り専用にしたり、固定サイズにしたり、コレクションに出入りするアイテムをチェックしたり、ビューを使用したりできます(C#ではGetRange、JavaではsubListを参照)。

ちなみに、ArrayListは常にプリミティブ配列に基づいている必要があります。そうでない場合、名前が間違っています。操作は通常、プリミティブ配列を使用するときに期待するとおりに実装されます。リンクリストが使用されている場合、通常はその名前が付けられます--LinkedList。これは、インターフェースを使用することの利点でもあります。後で、使用する実装について考えを変えることができます。

コレクションを不格好に利用することがいくつかあります。注意点の1つは、コレクションは通常オブジェクトに基づいており、言語にはプリミティブタイプとオブジェクトタイプの間にかなりのギャップがあることです。限られたジェネリックもあまり役に立ちません。それでも、特に理由がない限り、配列よりもコレクションをお勧めします。

プリミティブ値の場合は、プリミティブコレクションライブラリの使用を検討することもできます(例: GNU Trove )。ただし、C#に似たものがあるかどうかはわかりません。

1
Ronald Blaschke

コーディングのすばらしい冒険 は作品を書いています 配列はやや有害であると考えられています 。それは本当に興味深い読み物です。

1
doekman

こんな感じです。

using System;
using System.Collections;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            //ArrayList
            /*
             An ArrayList doesn't use a LinkedList as the internal data structure! .we can store any type of objects      
             */
            ArrayList list = new ArrayList();
            list.Add("1"); // not strongly type,you can enter any object types (int,string decimals, etc..)
            list.Add(1);
            list.Add(1.25);

            //Array
            /*
             must declare length.
             */
            string[] array = new string[3]; // you must declare object types
            array[0] = "1";
            //array[1] = 1; this get error becoz array is storngly typed. // this print empty value when you run it
            array[2] = "stongly typed";
            Console.WriteLine("------- ARRAYLIST ITEMS ---------");
            foreach (var i in list) {
                Console.WriteLine(i);
            }

            Console.WriteLine("--------- ARRAY ITEMS -----------");
            foreach (var i in array)
            {
                Console.WriteLine(i);
            }

            Console.ReadKey(); 
        }
    }
}
0
Elshan

プリミティブ型の配列が必要な場合は、自動ボックス化とボックス化解除を回避するため、パフォーマンスを向上させるために配列を使用します。ただし、事前に必要なサイズがわかっている場合に限ります。

0
endless

たとえば、特定の型のみを処理する場合は、ArrayListを使用しないでください。たとえば、バイトの配列のみが必要な場合は、バイトの配列のみを受け入れる必要があります。

Listの代わりにArrayListを使用することを考えてもよいと思うときだけです。

0
Spodi

配列のサイズは静的であるため、設計時にサイズがわかっている場合は、配列を使用してください。それはより速く動作するはずですが、私はそれを自分でテストしていません。オブジェクトの数を頻繁に変更する必要がある場合(コレクションにオブジェクトを追加または削除する場合)は、ArrayListまたは.NET 2の汎用Listを使用します。使いやすいため、パフォーマンスが重要でない場合は、いつでもListを使用できます。

0
Rumen Georgiev