bucket-sort logo bucket-sort

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

  • Posts
  • About
  • Contact
  1. Home
  2. All Posts
  3. [C#] System.Collections.Queue — 非ジェネリックな FIFO キューの仕組みと使いどころ

[C#] System.Collections.Queue — 非ジェネリックな FIFO キューの仕組みと使いどころ

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

System.Collections.Queue は、.NET Framework 1.0 から提供されている 非ジェネリックな FIFO(先入れ先出し)コレクション です。Queue<T>(.NET 2.0+)の登場で実用上は置き換えが完了していますが、System.Collections シリーズの一員として整理しておきます。

Queue とは

  • 名前空間:System.Collections
  • 内部構造:循環バッファ(リングバッファ)。object[] + head + tail + size
  • 容量超過時は新しい配列に詰め替え(既定は growFactor = 2.0 で 2 倍に拡張)
  • 要素の型は object、値型はボックス化
using System.Collections;

var queue = new Queue();
queue.Enqueue("first");
queue.Enqueue("second");
queue.Enqueue("third");

string s = (string)queue.Dequeue()!; // "first"
string p = (string)queue.Peek()!;    // "second"(取り出さない)

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

インターフェース 役割
ICollection Count / CopyTo / 同期サポート
IEnumerable foreach で先頭から末尾の順に列挙
ICloneable Clone() で浅いコピー

IList は実装しません。任意位置のアクセス・挿入・削除をサポートしないコレクション だからです。これは Queue の「先頭の取り出し/末尾への追加」という純粋な FIFO セマンティクスを反映しています。

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

  • ICollection: ArrayList の記事
  • IEnumerable / IEnumerator: IEnumerable と IEnumerator の記事
  • ICloneable: ICloneable インターフェースの記事

Queue.Clone() は新しい配列バッファに要素参照をコピーする 浅いコピー です。

主な API と計算量

操作 API 計算量 備考
末尾追加 Enqueue(obj) O(1) 償却 容量超過時のみ O(n) で再確保
先頭取り出し Dequeue() O(1) head を進めるだけ
先頭参照 Peek() O(1) 取り出さずに先頭を見る
含有判定 Contains(obj) O(n) 線形探索
列挙 foreach O(n) 先頭から順に
配列化 ToArray() O(n)

Dequeue() を空のキューに対して呼ぶと InvalidOperationException。事前に Count を確認するか、空でないことを保証して呼び出します。

TrimToSize と容量管理

var q = new Queue(capacity: 1_000);
for (int i = 0; i < 500; i++) q.Enqueue(i);
q.TrimToSize(); // 内部配列を Count に合わせて縮小

長期間動く処理で大きく膨らんだまま縮まないキューがあるなら、定期的に TrimToSize を呼ぶか、Queue<T> の同様の API を使ってメモリ圧を下げます。

ボックス化のコスト

値型の要素を扱うと エンキュー時とデキュー時の両方 でボックス化/アンボックス化が発生します。

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

while (q.Count > 0)
{
    int x = (int)q.Dequeue()!; // アンボックス化 + キャスト
}

Queue<int> を使えばボックス化は発生せず、ヒープ割り当てもキャストもなくなるため、現代のコードでは Queue<T> 一択 です。

Queue<T> との比較

観点 Queue Queue<T>
型安全 × object のキャストが必要 ◯
値型のボックス化 発生 発生しない
推奨度 レガシー 新規コードの標準
パフォーマンス 劣る 良い
API ほぼ同じ(Enqueue/Dequeue/Peek) 同じ+TryDequeue/TryPeek

Queue<T>.TryDequeue(out T result) のような 空判定とのアトミック化 API がジェネリック版にしかない点も実用上の差です。

並行アクセス

Queue.Synchronized(queue) でスレッドセーフラッパが取れますが、粒度が粗いため現代では System.Collections.Concurrent.ConcurrentQueue<T> の利用が標準です。プロデューサ/コンシューマパターンには BlockingCollection<T> や Channel<T> のほうが適しています。

使いどころ

Queue / Queue<T> が活きる典型的な場面を見ておきます。

幅優先探索(BFS)

static IEnumerable<TNode> Bfs<TNode>(TNode start, Func<TNode, IEnumerable<TNode>> children)
{
    var visited = new HashSet<TNode>();
    var queue   = new Queue<TNode>();
    queue.Enqueue(start);
    visited.Add(start);

    while (queue.Count > 0)
    {
        var node = queue.Dequeue();
        yield return node;
        foreach (var c in children(node))
        {
            if (visited.Add(c)) queue.Enqueue(c);
        }
    }
}

生産者・消費者(単一スレッド・バッチ処理)

ジョブを順次積み、順次処理する典型的なバッチパターン。

var jobs = new Queue<Job>();
foreach (var j in incoming) jobs.Enqueue(j);
while (jobs.Count > 0) Process(jobs.Dequeue());

並行性が必要なら ConcurrentQueue<T> か Channel<T> に切り替えます。

直近 N 件のリングバッファ

固定サイズの履歴を保持したいときは、上限超過時に先頭を捨てるパターン。

void Push(Queue<string> log, string entry, int max)
{
    log.Enqueue(entry);
    while (log.Count > max) log.Dequeue();
}

これらいずれも Queue<T> で書くのが現代的。System.Collections.Queue を選ぶ理由はレガシー互換以外にありません。

まとめ

  • Queue は 非ジェネリックな FIFO。内部は循環バッファで Enqueue/Dequeue/Peek が O(1)。
  • ICollection / IEnumerable / ICloneable を実装。IList は実装しない。
  • 値型はボックス化されるため、新規コードでは Queue<T> 一択、並行なら ConcurrentQueue<T> か Channel<T>。
  • BFS、ジョブの順次処理、固定長の履歴管理が代表的な使いどころ。
C# .NET Queue System.Collections FIFO コレクション
← [C#] System.Collections.Hashtable — 非ジェネリックなハッシュテーブルの仕組みと使いどころ [C#] System.Collections.SortedList — キーで自動整列される連想配列の仕組みと使いどころ →

Related Posts

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

Table of Contents

  • Queue とは
  • サポートするインターフェース
  • 主な API と計算量
    • TrimToSize と容量管理
  • ボックス化のコスト
  • Queue<T> との比較
  • 並行アクセス
  • 使いどころ
    • 幅優先探索(BFS)
    • 生産者・消費者(単一スレッド・バッチ処理)
    • 直近 N 件のリングバッファ
  • まとめ

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.