bucket-sort logo bucket-sort

プログラミングとインフラエンジニアリングの覚え書き

  • Posts
  • About
  • Contact
  1. Home
  2. All Posts
  3. [C#] System.Collections.ArrayList — 可変長配列(非ジェネリック)の仕組みと使いどころ

[C#] System.Collections.ArrayList — 可変長配列(非ジェネリック)の仕組みと使いどころ

May 15, 2026 C# , .NET bucket-sort

System.Collections.ArrayList は、.NET Framework 1.0 から提供されている 可変長の非ジェネリック配列 です。List<T> がジェネリックの登場(.NET 2.0)以降に主役を譲ったため新規コードで使うことは推奨されませんが、レガシーコードや一部の COM 連携、DataTable 関連の API ではいまだに目にします。本記事では ArrayList の 内部構造・インターフェース・性能特性・使いどころ を整理します。

ArrayList とは

  • 名前空間:System.Collections
  • 内部構造:object[] バッファ + 現在の要素数 Count + 確保済み容量 Capacity
  • 容量が足りなくなると 倍々(× 2)に拡張(最初は 4 から始まる)
  • 要素の型はすべて object。値型は ボックス化 されて格納される
using System.Collections;

var list = new ArrayList();
list.Add(1);          // int → object にボックス化
list.Add("hello");    // 参照型はそのまま
list.Add(3.14);       // double → object にボックス化

int n = (int)list[0]; // 取り出すときはキャストが必須

すべて object 経由で扱うため、型安全でなく、値型ではボックス化のオーバーヘッドが発生 します。これが List<T> に取って代わられた最大の理由です。

サポートするインターフェース

ArrayList は次のインターフェースを実装しています。

インターフェース 役割
IList 添字アクセス・挿入・削除を持つ順序付きコレクション
ICollection Count・CopyTo・同期サポートなどコレクション共通機能
IEnumerable foreach で列挙可能
ICloneable Clone() による浅いコピーをサポート

IList

IList は インデックスでアクセスできるコレクション を表すインターフェースです。ArrayList の中核となる機能はすべてこのインターフェース由来です。

public interface IList : ICollection
{
    object? this[int index] { get; set; }
    int Add(object? value);
    void Insert(int index, object? value);
    void Remove(object? value);
    void RemoveAt(int index);
    bool Contains(object? value);
    int IndexOf(object? value);
    void Clear();
    bool IsFixedSize { get; }
    bool IsReadOnly { get; }
}

ICollection

ICollection は要素数の取得とコピー、スレッド同期サポートを規定する基底インターフェースです。

public interface ICollection : IEnumerable
{
    int Count { get; }
    object SyncRoot { get; }
    bool IsSynchronized { get; }
    void CopyTo(Array array, int index);
}

SyncRoot を使った排他制御は古い設計で、現在は lock (専用オブジェクト) か並行コレクション(System.Collections.Concurrent)の利用が推奨されます。

IEnumerable / ICloneable

IEnumerable の詳細は IEnumerable と IEnumerator の記事 を、ICloneable の浅いコピーと深いコピーの違いは ICloneable インターフェースの記事 を参照してください。

ArrayList.Clone() は 浅いコピー を返します。要素が参照型の場合、参照だけがコピーされる点に注意してください。

var src = new ArrayList { new[] { 1, 2, 3 } };
var dst = (ArrayList)src.Clone();
((int[])dst[0])[0] = 99;
Console.WriteLine(((int[])src[0])[0]); // 99(同じ配列を共有)

主な API と計算量

操作 API 平均計算量 備考
末尾追加 Add(obj) O(1) 償却 容量超過時は O(n) で再確保
末尾削除 RemoveAt(Count - 1) O(1)
添字アクセス list[i] O(1) 配列と同じ
任意位置挿入 Insert(i, obj) O(n) 後続要素を 1 つずらす
任意位置削除 RemoveAt(i) / Remove(obj) O(n)
検索 Contains / IndexOf O(n) 線形探索
ソート Sort() O(n log n) 内部は Array.Sort
二分探索 BinarySearch(obj) O(log n) 事前に整列が必要

Capacity を事前に設定すると再確保を防げます。要素数の見当が付くなら必ず指定しましょう。

var list = new ArrayList(capacity: 10_000);
for (int i = 0; i < 10_000; i++) list.Add(i);
list.TrimToSize(); // Capacity を Count まで切り詰める

ボックス化のコスト

ArrayList の最大の落とし穴は 値型のボックス化 です。

var arr = new ArrayList();
for (int i = 0; i < 1_000_000; i++) arr.Add(i); // 100 万回ボックス化

long sum = 0;
foreach (var x in arr) sum += (int)x; // 100 万回アンボックス化

ヒープ割り当てと GC 圧、キャスト命令のコストが積み重なり、List<int> と比べて 数倍~10 倍以上遅くなる ことも珍しくありません。値型を扱うなら無条件に List<T> を選ぶべきです。

List<T> との比較

観点 ArrayList List<T>
型安全 × object のキャストが必要 ◯ コンパイル時に保証
値型のボックス化 発生する 発生しない
パフォーマンス 劣る 良い
LINQ 対応 Cast<T>() 経由で必要 そのまま使える
推奨度 新規コードでは非推奨 標準

新規コードでは 常に List<T> を使うのが鉄則です。

使いどころ

ジェネリックの登場以降、ArrayList を積極的に選ぶ理由はほぼありません。実務で出会うのは次のような場面です。

  1. レガシーコードのメンテナンス:.NET Framework 1.x 時代から続くコードベース。
  2. COM 相互運用や古い API:戻り値が ArrayList や IList のままになっている API。
  3. 動的な異種要素の集合:型が混在し object で扱うのが妥当な場面。とはいえ現在は List<object> で十分です。
  4. 学習目的:コレクションの内部実装(容量倍々拡張など)を理解する材料として。

ArrayList から List<T> への移行

// Before
ArrayList legacy = GetLegacyList(); // 中身は string が入っているとする
foreach (object o in legacy)
{
    string s = (string)o;
    Console.WriteLine(s.ToUpper());
}

// After(LINQ の Cast<T> で型付き列挙に変換)
foreach (string s in legacy.Cast<string>())
{
    Console.WriteLine(s.ToUpper());
}

// さらに安全に:実体ごと List<string> へ移す
List<string> modern = legacy.Cast<string>().ToList();

API 境界が IList で型が固定的に決まっている場合、Cast<T>() で挟むだけでも型安全な世界に橋渡しできます。

まとめ

  • ArrayList は 非ジェネリックな可変長配列。内部は object[]。
  • IList / ICollection / IEnumerable / ICloneable を実装。
  • 添字アクセスは O(1)、末尾追加は O(1) 償却、任意位置の挿入・削除は O(n)。
  • 値型を入れると ボックス化が起きる。新規コードでは List<T> 一択。
  • レガシー API との接続点でだけ顔を出す存在。出会ったら Cast<T>() で素早く型安全な世界に持ち込もう。

次回以降、BitArray / Hashtable / Queue / SortedList / Stack と、System.Collections の他のクラスを順に扱います。

C# .NET ArrayList System.Collections コレクション パフォーマンス
← [C#] Lazy Object Instantiation — 遅延初期化と Lazy<T> の使いどころ [C#] System.Collections.BitArray — ビット列を効率的に扱う固定長コレクション →

Related Posts

  • [C#] System.Collections.Stack — 非ジェネリックな LIFO スタックの仕組みと使いどころ May 20, 2026
  • [C#] System.Collections.SortedList — キーで自動整列される連想配列の仕組みと使いどころ May 19, 2026
  • [C#] System.Collections.Queue — 非ジェネリックな FIFO キューの仕組みと使いどころ May 18, 2026
  • [C#] System.Collections.Hashtable — 非ジェネリックなハッシュテーブルの仕組みと使いどころ May 17, 2026

Table of Contents

  • ArrayList とは
  • サポートするインターフェース
    • IList
    • ICollection
    • IEnumerable / ICloneable
  • 主な API と計算量
  • ボックス化のコスト
  • List<T> との比較
  • 使いどころ
  • ArrayList から List<T> への移行
  • まとめ

Recent Posts

  • [C#] System.Collections.Specialized.ListDictionary — 小規模辞書に特化した連結リスト実装 May 22, 2026
  • [C#] System.Collections.Specialized.HybridDictionary — 小規模では ListDictionary、大規模では Hashtable May 21, 2026
  • [C#] System.Collections.Stack — 非ジェネリックな LIFO スタックの仕組みと使いどころ May 20, 2026
  • [C#] System.Collections.SortedList — キーで自動整列される連想配列の仕組みと使いどころ May 19, 2026
  • [C#] System.Collections.Queue — 非ジェネリックな FIFO キューの仕組みと使いどころ May 18, 2026

Categories

  • C#72
  • .NET71
  • AWS27
  • Laravel16
  • Linux15
  • MySQL9
  • Apache8
  • PHP8
  • DynamoDB6
  • セキュリティ6
  • Nginx5
  • WordPress4
  • インフラ4
  • Hugo3
  • .NET Framework1
  • Aurora1
  • Filament1
  • Git1
  • SQS1

Tags

  • C#
  • .NET
  • AWS
  • Laravel
  • PHP
  • セキュリティ
  • MySQL
  • Linux
  • コレクション
  • Apache
  • パフォーマンス
  • Code Snippet
  • DynamoDB
  • NoSQL
  • PHP-FPM
  • RDS
  • System.Collections
  • DoS
  • Nginx
  • Windows
  • WordPress
  • メモリ管理
  • 監視
  • 設計
  • Amazon Linux 2023
  • Docker
  • IDisposable
  • Ipset
  • Iptables
  • OPCache
  • Webサーバー
  • オブジェクト指向
  • クラス設計
  • デザインパターン
  • パターンマッチング
  • 継承
  • 認可
  • Aurora
  • Blade
  • Grafana
  • Hugo
  • InfluxDB
  • Policy
  • Record
  • SSG
  • インターフェース
  • エラーハンドリング
  • カプセル化
  • ガベージコレクション
  • モニタリング
Powered by Hugo & Explore Theme.