C#のArrayListとHashtableは基本的に非推奨

C#のArrayListとHashtableは非推奨

2018年に新規にArrayListの使い方を説明するWebページがあったりしますが、C#のArrayListは現在利用は推奨できません。代わりにList<T>クラスを使用しましょう

Javaを学習した方がC#に動的配列の機能を探して同じ機能が無いか探してC#にArrayLiatクラスがある事を発見して可変長リストでArrayListを使用するケースがあると思います。しかし、C#のArrayListは現在利用は推奨できません。

同じくキーと値の組み合わせでオブジェクトを管理できる(=連想配列)クラスにHashtableクラスがありますがこれも利用は推奨できません。

ArrayListやHashtableはC#にジェネリックが導入される以前の.NET1.0時代(=今から15年以上前)の機能であり、互換性のために残されている状態です。新規にコードを書くときは際はそれぞれに対応するList<T>、Dictionary<TKey, TValue>が現在の推奨です。それぞれ名前が違いますが同様の機能がより安全に利用できます。

というか、System.Collections名前空間にあるクラスは全て上記のによる理由の極めて古いクラス群のなので、System.Collections.Genericにある型を使用しましょう。

非推奨の型(System.Collections) 新しい型(System.Collections.Generic) 説明
ArrayList () List<T> 動的配列として利用できる
Hashtable Dictionary<TKey, TValue> キーと値をペアで管理できる連想配列

ArrayListやHashtableが非推奨な理由

一部の型でパフォーマンスが悪い

C#のArrayListやHashtableは、なんでも入れられるobject型の入れ物となりますが、intやらbyte等の組み込み型をArrayListに入れてしまうと、int → Object → int という型変換の過程でボックス化・アンボックス化が発生してしまいパフォーマンスが低下します。

以下はほんの一例ですが、単純な追加でも3倍ほどArrayListが遅いです。

public static void Main(string[] args)
{
    var r = new Random();

    var sw1 = new Stopwatch();
    var sw2 = new Stopwatch();

    var aList = new ArrayList();
    var glist = new List<int>();

    for (int i = 0; i < 1000000; i++)
    {
        int p = r.Next();

        sw1.Start(); // ArrayList に追加する時間を計測
        aList.Add(p);
        sw1.Stop();

        sw2.Start(); // List<int> に追加する時間を計測
        glist.Add(p);
        sw2.Stop();
    }

    Console.WriteLine($"Time1 : {sw1.Elapsed}");
    Console.WriteLine($"Time2 : {sw2.Elapsed}");
    // > Time1: 00:00:00.0992377 ★★★遅い!!!
    // > Time2: 00:00:00.0372167
}

新しいクラスでも以下のように宣言すればArrayListやHashtableと同じように使用できます。(ほとんどメリットは無いと思いますが…

var asArrayList = new List<object>();
var asHashtable = new Ditionary<object, object>();

いちいち内容を確認しないといけない

Object型でなんでもデータが入っていると、取り出して内容を使用する際に目的の型がどうかチェックしないといけません。

また、リストに入れるデータも制限ができないので、(自分ひとりで使用している限りはまぁ大丈夫かと思いますが)トラブルの元になります。

// このように何でも入れられる
var alist = new ArrayList()
{
    new object(),
    100,
    1.275,
    TimeSpan.FromDays(1),
};

こんな風にリストに入れられても使うときに困りこそしますが、メリットが全くありません。

Dictionary<Tkey, TValue>List<T>を使いましょう

とにかくList<T>, Dictionary<Tkey, TValue>を使いましょう。

そしてSystem.Collectionsに所属するクラスはSystem.Collection.Genericに置換機能があるのでそちらを使用しましょう。