bucket-sort logo bucket-sort

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

  • Posts
  • About
  • Contact
  1. Home
  2. All Posts
  3. [C#] System.Collections.Generic.List<T> — もっとも使われる動的配列の仕組みと使いどころ

[C#] System.Collections.Generic.List<T> — もっとも使われる動的配列の仕組みと使いどころ

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

System.Collections.Generic.List<T> は、C# でもっとも頻繁に使われるコレクションです。型安全な動的配列 として、配列のシンプルさとサイズの可変性を両立しています。本記事では内部実装、サポートインターフェース、性能特性、実務での使いどころを整理します。

List<T> とは

  • 名前空間:System.Collections.Generic
  • 内部構造:T[] バッファ + _size(要素数)+ Capacity(確保済み容量)
  • 容量超過時は 2 倍に拡張(実装は T[Capacity * 2] を確保して Array.Copy)
  • T は参照型・値型どちらもボックス化なしで格納できる
var list = new List<int> { 1, 2, 3 };
list.Add(4);
list.Insert(0, 0);  // 先頭挿入:O(n)
list.RemoveAt(2);

int x = list[1];     // インデックスアクセス:O(1)

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

インターフェース 役割
IList<T> インデックスアクセス・挿入・削除を持つ順序付きコレクション
IReadOnlyList<T> インデックスアクセスのみ、書き換え不可ビュー
ICollection<T> Count / Add / Remove / CopyTo 等
IReadOnlyCollection<T> 読み取り専用の Count
IEnumerable<T> foreach での列挙
IList / ICollection / IEnumerable 非ジェネリック版(互換)

各インターフェースの詳細は次を参照してください。

  • IList / ICollection: ArrayList の記事
  • IEnumerable / IEnumerator: IEnumerable と IEnumerator の記事

IList<T> はジェネリックなインデックス付きコレクションを表します。

public interface IList<T> : ICollection<T>
{
    T this[int index] { get; set; }
    int IndexOf(T item);
    void Insert(int index, T item);
    void RemoveAt(int index);
}

API 境界には 読み取り専用なら IReadOnlyList<T>、書き換え可なら IList<T> を指定するのが基本。List<T> を直接公開すると外部が拡張・縮小できてしまうので避けましょう。

主な API と計算量

操作 API 計算量 備考
インデックスアクセス list[i] O(1)
末尾追加 Add(item) O(1) 償却 容量超過時は O(n)
範囲追加 AddRange(items) O(k)
任意位置挿入 Insert(i, item) O(n) 後続要素を 1 つずらす
任意位置削除 RemoveAt(i) / Remove(item) O(n)
末尾削除 RemoveAt(Count - 1) O(1)
検索 Contains / IndexOf O(n) 線形探索
ソート Sort() O(n log n) 内部は Array.Sort
二分探索 BinarySearch(item) O(log n) 事前に整列が必要
範囲削除 RemoveAll(predicate) O(n) フィルタリングを兼ねる

Capacity と EnsureCapacity

要素数の見当が付くなら 必ず Capacity を指定 することで、再確保とコピーの回数を減らせます。

var list = new List<int>(capacity: 1_000_000);
for (int i = 0; i < 1_000_000; i++) list.Add(i);

.NET 6+ では EnsureCapacity(min) で動的に拡張できます。逆に縮める TrimExcess() も用意されています。

list.EnsureCapacity(2_000_000);
list.TrimExcess();

高効率アクセス — Span<T> と CollectionsMarshal

ホットパスで List<T> を回すなら、CollectionsMarshal.AsSpan(list) で内部配列に直接アクセスする Span<T> が取れます(.NET 5+)。境界チェックの省略やベクトル化と組み合わせて非常に高速です。

using System.Runtime.InteropServices;

Span<int> span = CollectionsMarshal.AsSpan(list);
for (int i = 0; i < span.Length; i++) span[i] *= 2;

ただし AsSpan 後にリストの構造を変更(Add/Insert/Remove)してはいけません。Span が無効な内部配列を指す可能性があります。

ボックス化はしない

List<int> は内部が int[] なので、int をそのまま格納します。object[] に詰める ArrayList のようなボックス化コストは発生しません。値型のコレクションは無条件に List<T> を選ぶのが鉄則。

配列・LinkedList<T> との比較

観点 T[](配列) List<T> LinkedList<T>
サイズ 固定 可変 可変
インデックスアクセス O(1) O(1) 非対応
末尾追加 × O(1) 償却 O(1)
任意位置挿入(位置既知) × O(n) O(1)(ノード既知時)
メモリオーバーヘッド 最小 配列+少量 ノードあたり前後ポインタ
キャッシュ局所性 高 高 低

「サイズが固定 & 最高速」が要件なら配列、それ以外はほぼ List<T>。LinkedList<T> は LRU キャッシュなどの特殊な用途に限定されます。

使いどころ

List<T> は 「迷ったらこれ」 の汎用ツールです。

  • 任意の集合の保持・列挙
  • 配列より柔軟に伸縮させたい
  • LINQ で射影・フィルタの起点にする
  • API の戻り値で順序付き集合を返す(公開 API では IReadOnlyList<T> で)

並行アクセスが必要なら ConcurrentBag<T> / ConcurrentQueue<T> / 自前ロック、要素数が極端に少なく頻繁に作って捨てるなら Span<T>/stackalloc を検討します。

イディオム

列挙中の削除

list.RemoveAll(x => x.IsExpired);    // O(n) で済む。ループより高速

ループでの Remove は O(n²) になるので、RemoveAll か 逆順インデックスループ を使います。

for (int i = list.Count - 1; i >= 0; i--)
    if (list[i].IsExpired) list.RemoveAt(i);

配列との相互変換

int[] arr = list.ToArray();           // 新しい配列にコピー
var copy  = new List<int>(arr);       // 配列から List を作る
ReadOnlySpan<int> span = CollectionsMarshal.AsSpan(list); // 内部参照

不変ビューの公開

public IReadOnlyList<Item> Items => _items;  // 内部の List<Item> を読み取り専用で公開

外部から書き換えさせたくない場合の基本。完全な不変が必要なら ImmutableList<T> か ReadOnlyCollection<T>(AsReadOnly())を使います。

注意点

  • 列挙中の変更は例外:foreach 中に Add/Remove/Insert を呼ぶと InvalidOperationException。
  • スレッドセーフではない:並行アクセスには別途ロック、または ConcurrentBag<T> 等を選択。
  • Capacity != Count:Count は要素数、Capacity は確保済み容量。TrimExcess で寄せられる。

まとめ

  • List<T> は C# のもっとも標準的な動的配列。インデックスアクセス O(1)、末尾追加 O(1) 償却。
  • IList<T> / IReadOnlyList<T> / ICollection<T> / IEnumerable<T> 等を実装。
  • 値型もボックス化なしで格納できる。ArrayList は使わない。
  • 容量を事前指定して再確保を抑える、CollectionsMarshal.AsSpan で高効率に走査するなど、ホットパスでの最適化手段が用意されている。
  • 「迷ったら List<T>」。順序付き集合の事実上の標準。
C# .NET List System.Collections.Generic コレクション パフォーマンス
← [C#] System.Collections.Generic.LinkedList<T> — 双方向連結リストの仕組みと使いどころ [C#] System.Collections.Generic.Queue<T> — 型安全な FIFO キューの仕組みと使いどころ →

Related Posts

  • [C#] System.Collections.Generic.Stack<T> — 型安全な LIFO スタックの仕組みと使いどころ May 31, 2026
  • [C#] System.Collections.Generic.SortedSet<T> — 赤黒木で実装される整列セット May 30, 2026
  • [C#] System.Collections.Generic. SortedDictionary<TKey, TValue> — 赤黒木で実装される整列辞書 May 29, 2026
  • [C#] System.Collections.Generic.Queue<T> — 型安全な FIFO キューの仕組みと使いどころ May 28, 2026

Table of Contents

  • List<T> とは
  • サポートするインターフェース
  • 主な API と計算量
  • Capacity と EnsureCapacity
  • 高効率アクセス — Span<T> と CollectionsMarshal
  • ボックス化はしない
  • 配列・LinkedList<T> との比較
  • 使いどころ
  • イディオム
    • 列挙中の削除
    • 配列との相互変換
    • 不変ビューの公開
  • 注意点
  • まとめ

Recent Posts

  • [C#] ジェネリックの型制約(Constraining Type Parameters)入門 — where T : struct / class / new() / 基底クラス / インターフェース Jun 3, 2026
  • [C#] System.Collections.ObjectModel. ReadOnlyObservableCollection<T> — 変更通知付きの読み取り専用ビュー Jun 2, 2026
  • [C#] System.Collections.ObjectModel. ObservableCollection<T> — 変更通知付きコレクションの仕組みと使いどころ Jun 1, 2026
  • [C#] System.Collections.Generic.Stack<T> — 型安全な LIFO スタックの仕組みと使いどころ May 31, 2026
  • [C#] System.Collections.Generic.SortedSet<T> — 赤黒木で実装される整列セット May 30, 2026

Categories

  • C#84
  • .NET83
  • 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
  • System.Collections.Generic
  • Code Snippet
  • DynamoDB
  • NoSQL
  • PHP-FPM
  • RDS
  • System.Collections
  • DoS
  • Nginx
  • Windows
  • WordPress
  • メモリ管理
  • 監視
  • 設計
  • Amazon Linux 2023
  • Docker
  • IDisposable
  • Ipset
  • Iptables
  • OPCache
  • System.Collections.Specialized
  • Webサーバー
  • オブジェクト指向
  • クラス設計
  • デザインパターン
  • パターンマッチング
  • 継承
  • 認可
  • Aurora
  • Blade
  • Grafana
  • Hugo
  • InfluxDB
  • Policy
  • Record
  • SSG
  • WPF
  • インターフェース
  • エラーハンドリング
Powered by Hugo & Explore Theme.