← SEARCHABLE ARCHIVE
C# · 2026-08-02

C# 基礎からマスターまで — 第6回

コレクションとLINQでデータを扱う

INTERACTIVE READING MODE →

本ブログ作成文は、講義を目指して製作されました。 また、作成された文章の情報も間違っている可能性がありますので、ご注意ください。

ゲームとアプリは多くのデータを保存、検索、並べ替えます。 コレクションを目的に合わせて均等にLINQで処理意図を表現すると、コードが短くなるよりも流れが鮮明になる。

コレクションを選択

var party = new List<Player>();
var itemById = new Dictionary<int, Item>();
var unlockedIds = new HashSet<int>();

itemById.Add(10, new Item(10, "Potion"));
unlockedIds.Add(10);

Listは順序付きリスト、Dictionaryはキー検索、HashSetは値の存在と重複防止に適しています。 Dictionaryにないキーをインデクサーに読み込むと例外が発生するため、TryGetValueを使用できます。

LINQで問い合わせる

List<Monster> targets = monsters
    .Where(monster => monster.IsAlive)
    .OrderBy(monster => monster.Health)
    .Take(3)
    .ToList();

生きているモンスターの中で体力の低い三匹を選ぶという意図が演算の順番に現れる。 LINQは元のコレクションを自動的に変更せずに新しい結果フローを作成します。

遅延実行

IEnumerable<Monster> alive = monsters.Where(monster => monster.IsAlive);

monsters.Add(new Monster());

foreach (Monster monster in alive)
{
    Console.WriteLine(monster.Health);
}

Whereが返したクエリは通常巡回する時点で実行されます。 途中でオリジナルが変わると結果も変わることがあり、現在の結果を固定するにはToList()で直ちに計算します。

繰り返しコストを確認する

LINQ呼び出しが無条件に遅いわけではありませんが、イテレータ、デリゲート、結果のコレクションを作成できます。 フレームごとに何千回も実行されるパスであれば、単純な繰り返しステートメントとバッファの再利用がより適している可能性があります。

targets.Clear();
foreach (Monster monster in monsters)
{
    if (monster.IsAlive)
    {
        targets.Add(monster);
    }
}

まず、読みやすいクエリを作成し、実際の測定で問題が確認された区間だけを変更するのが良い。 コレクションとLINQの鍵は、最も短い文法ではなく、データの保存目的と処理時点を明確にすることです。