# 機能設計書: System.Linq（LINQ）

## 1. 機能概要

### 1.1 機能名
System.Linq（LINQ - Language Integrated Query）

### 1.2 機能ID
FUNC-012

### 1.3 機能説明
.NET ランタイムにおけるLanguage Integrated Query（LINQ）機能を提供するライブラリ。コレクション、配列、データソースに対するクエリ操作を宣言的に記述できる。フィルタリング、射影、集計、結合、グループ化などの豊富なクエリ演算子を拡張メソッドとして提供し、遅延評価によるメモリ効率の良い処理を実現する。

### 1.4 関連画面
- なし（基盤ライブラリのため直接的な関連画面は存在しない）

## 2. 機能要件

### 2.1 入力仕様

| 項目名 | データ型 | 必須 | 説明 |
|--------|----------|------|------|
| source | IEnumerable<T> | Yes | クエリ対象のコレクション |
| predicate | Func<T, bool> | No | フィルタ条件式 |
| selector | Func<T, TResult> | No | 射影関数 |
| keySelector | Func<T, TKey> | No | キー選択関数 |
| comparer | IEqualityComparer<T> | No | 比較子 |

### 2.2 出力仕様

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| IEnumerable<T> | IEnumerable<T> | 遅延評価されるシーケンス |
| T | T | 単一要素（First, Single等） |
| bool | bool | 判定結果（Any, All, Contains等） |
| int | int | カウント、インデックス |
| T[] | T[] | 配列変換結果 |
| List<T> | List<T> | リスト変換結果 |

### 2.3 処理フロー

```
IEnumerable<T> ソース
    │
    ▼
┌─────────────────────┐
│  クエリ演算子連鎖      │
│  .Where().Select()...│
└─────────────────────┘
    │
    ▼ (遅延評価)
┌─────────────────────┐
│  Iterator パターン    │
│  GetEnumerator()     │
└─────────────────────┘
    │
    ▼ (列挙時に実行)
┌─────────────────────┐
│  要素の遅延取得       │
│  MoveNext()/Current  │
└─────────────────────┘
    │
    ▼
結果シーケンス
```

## 3. 詳細設計

### 3.1 クラス構成

#### 3.1.1 主要クラス

| クラス名 | 責務 |
|----------|------|
| Enumerable | IEnumerable<T>向けLINQ演算子の拡張メソッド群 |
| Queryable | IQueryable<T>向けLINQ演算子（式木ベース） |
| Iterator<T> | 遅延評価を実現する内部イテレータ基底クラス |
| Lookup<TKey, TElement> | キーによるグループ化結果を格納 |
| OrderedEnumerable<T> | ソート済みシーケンスを表現 |
| Grouping<TKey, TElement> | グループ化された要素を表現 |

### 3.2 演算子カテゴリ

#### 3.2.1 フィルタリング演算子

| メソッド | 説明 | 遅延/即時 |
|----------|------|-----------|
| Where | 条件に一致する要素を抽出 | 遅延 |
| OfType<T> | 指定型の要素のみ抽出 | 遅延 |
| Distinct | 重複を除去 | 遅延 |
| DistinctBy | キーによる重複除去 | 遅延 |

#### 3.2.2 射影演算子

| メソッド | 説明 | 遅延/即時 |
|----------|------|-----------|
| Select | 各要素を変換 | 遅延 |
| SelectMany | 各要素を複数要素に展開 | 遅延 |
| Cast<T> | 要素を指定型にキャスト | 遅延 |
| Chunk | 指定サイズのチャンクに分割 | 遅延 |

#### 3.2.3 ソート演算子

| メソッド | 説明 | 遅延/即時 |
|----------|------|-----------|
| OrderBy | 昇順ソート | 遅延 |
| OrderByDescending | 降順ソート | 遅延 |
| ThenBy | 二次ソート（昇順） | 遅延 |
| ThenByDescending | 二次ソート（降順） | 遅延 |
| Reverse | 逆順 | 遅延 |
| Order | 要素自体でソート | 遅延 |

#### 3.2.4 グループ化演算子

| メソッド | 説明 | 遅延/即時 |
|----------|------|-----------|
| GroupBy | キーでグループ化 | 遅延 |
| ToLookup | ルックアップに変換 | 即時 |

#### 3.2.5 結合演算子

| メソッド | 説明 | 遅延/即時 |
|----------|------|-----------|
| Join | 内部結合 | 遅延 |
| GroupJoin | グループ結合 | 遅延 |
| Zip | 要素ペアを結合 | 遅延 |
| Concat | シーケンス連結 | 遅延 |
| Union | 和集合 | 遅延 |
| Intersect | 積集合 | 遅延 |
| Except | 差集合 | 遅延 |

#### 3.2.6 集計演算子

| メソッド | 説明 | 遅延/即時 |
|----------|------|-----------|
| Count | 要素数 | 即時 |
| Sum | 合計 | 即時 |
| Min | 最小値 | 即時 |
| Max | 最大値 | 即時 |
| Average | 平均 | 即時 |
| Aggregate | カスタム集計 | 即時 |

#### 3.2.7 要素演算子

| メソッド | 説明 | 遅延/即時 |
|----------|------|-----------|
| First | 最初の要素 | 即時 |
| FirstOrDefault | 最初の要素またはデフォルト | 即時 |
| Last | 最後の要素 | 即時 |
| LastOrDefault | 最後の要素またはデフォルト | 即時 |
| Single | 唯一の要素 | 即時 |
| SingleOrDefault | 唯一の要素またはデフォルト | 即時 |
| ElementAt | 指定位置の要素 | 即時 |
| DefaultIfEmpty | 空なら既定値を返す | 遅延 |

#### 3.2.8 量子化演算子

| メソッド | 説明 | 遅延/即時 |
|----------|------|-----------|
| Any | 条件を満たす要素が存在するか | 即時 |
| All | 全要素が条件を満たすか | 即時 |
| Contains | 要素が含まれるか | 即時 |
| SequenceEqual | シーケンス同一判定 | 即時 |

#### 3.2.9 変換演算子

| メソッド | 説明 | 遅延/即時 |
|----------|------|-----------|
| ToArray | 配列に変換 | 即時 |
| ToList | Listに変換 | 即時 |
| ToDictionary | Dictionaryに変換 | 即時 |
| ToHashSet | HashSetに変換 | 即時 |
| AsEnumerable | IEnumerableとして返す | 遅延 |

#### 3.2.10 生成演算子

| メソッド | 説明 | 遅延/即時 |
|----------|------|-----------|
| Range | 整数シーケンス生成 | 遅延 |
| Repeat | 要素の繰り返し | 遅延 |
| Empty | 空シーケンス | 遅延 |

### 3.3 メソッド仕様（主要）

#### 3.3.1 Where()

```csharp
public static IEnumerable<TSource> Where<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, bool> predicate);

public static IEnumerable<TSource> Where<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, int, bool> predicate); // インデックス付き
```

**処理内容**（Where.cs: 12-51行目）:
1. source と predicate の null チェック
2. source の型に応じた最適なイテレータを選択
   - Iterator<TSource>: 既存イテレータの Where を呼び出し
   - TSource[]: ArrayWhereIterator を使用
   - List<TSource>: ListWhereIterator を使用
   - その他: IEnumerableWhereIterator を使用
3. 遅延評価されるイテレータを返却

#### 3.3.2 Select()

```csharp
public static IEnumerable<TResult> Select<TSource, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, TResult> selector);

public static IEnumerable<TResult> Select<TSource, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, int, TResult> selector); // インデックス付き
```

**処理内容**（Select.cs: 13-71行目）:
1. source と selector の null チェック
2. Native AOT 最適化のための型判定
3. source の型に応じた最適なイテレータを選択
   - Iterator<TSource>: 既存イテレータの Select を呼び出し
   - TSource[]: ArraySelectIterator を使用
   - List<TSource>: ListSelectIterator を使用
   - IList<TSource>: IListSelectIterator を使用
   - その他: IEnumerableSelectIterator を使用

### 3.4 遅延評価の仕組み

#### 3.4.1 Iteratorパターン

```csharp
private abstract class Iterator<TSource> : IEnumerable<TSource>, IEnumerator<TSource>
{
    protected int _state;
    protected TSource _current = default!;

    public TSource Current => _current;

    public abstract bool MoveNext();
    public abstract void Dispose();
    private protected abstract Iterator<TSource> Clone();
}
```

#### 3.4.2 状態管理
- _state = 0: 初期状態
- _state = 1: 列挙開始
- _state = 2: 列挙中
- _state = -1: 破棄済み

### 3.5 性能最適化

#### 3.5.1 型別最適化
- **Array**: インデックスアクセスによる高速列挙
- **List<T>**: 内部配列への直接アクセス
- **IList<T>**: インデックス付きアクセス
- **IEnumerable<T>**: 汎用イテレータ

#### 3.5.2 パイプライン最適化
- Where + Select の融合（WhereSelectIterator）
- Take + Where の最適化
- Count の ICollection<T> 対応

## 4. エラー処理

### 4.1 例外一覧

| 例外 | 発生条件 |
|------|----------|
| ArgumentNullException | source または必須パラメータが null |
| ArgumentOutOfRangeException | インデックスが範囲外 |
| InvalidOperationException | シーケンスが空（First, Single等） |
| OverflowException | 集計結果のオーバーフロー |

### 4.2 エラーハンドリング方針
- null チェックは ThrowHelper 経由で集約
- OrDefault バリアントで例外回避オプション提供
- TryGet パターンのサポート（.NET 6以降）

## 5. セキュリティ考慮事項

### 5.1 メモリ使用量
- 遅延評価により大規模データの効率的処理が可能
- ToArray/ToList は即時評価のためメモリ消費に注意
- 無限シーケンスに対する即時評価演算子の使用を避ける

### 5.2 パフォーマンス
- 複数回列挙は再計算されるため、必要に応じてキャッシュ
- 長いパイプラインはデバッグが困難になる可能性

## 6. コードリーディングガイド

### 6.1 推奨読解順序

1. **エントリーポイント**
   - `Enumerable.cs`: 静的クラス宣言とpartial定義

2. **基本演算子**
   - `Where.cs`: フィルタリングの基本実装
   - **12-51行目**: Where メソッドのオーバーロード
   - **94-146行目**: IEnumerableWhereIterator の実装
   - `Select.cs`: 射影の基本実装
   - **13-71行目**: Select メソッドのオーバーロード

3. **イテレータ基盤**
   - `Iterator.cs`: 遅延評価の基底クラス
   - `Utilities.cs`: ユーティリティ関数

4. **集計演算子**
   - `Sum.cs`, `Count.cs`, `Min.cs`, `Max.cs`: 即時評価演算子

### 6.2 プログラム呼び出し階層図

```
source.Where(predicate).Select(selector).ToList()
    │
    ├── Where(predicate)
    │       │
    │       └── new ArrayWhereIterator(source, predicate)
    │               [遅延: イテレータオブジェクト作成のみ]
    │
    ├── Select(selector)
    │       │
    │       └── ArrayWhereIterator.Select(selector)
    │               │
    │               └── new ArrayWhereSelectIterator(source, predicate, selector)
    │                       [遅延: 融合イテレータ作成]
    │
    └── ToList()
            │
            └── new List<TResult>(source)
                    │
                    ├── GetEnumerator()
                    │       │
                    │       └── Clone() [新しいイテレータ取得]
                    │
                    └── while (MoveNext())
                            │
                            ├── predicate(item) → false → 次へ
                            │
                            └── predicate(item) → true
                                    │
                                    └── selector(item) → 結果を追加
```

### 6.3 データフロー図

```
┌──────────────────┐
│ IEnumerable<T>   │
│ ソースシーケンス   │
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ Where(predicate) │  ← 遅延: Iterator作成
│ フィルタリング     │
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ Select(selector) │  ← 遅延: Iterator融合
│ 射影             │
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ ToList()         │  ← 即時: 列挙実行
│ 具体化           │
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ List<TResult>    │
│ 結果リスト        │
└──────────────────┘
```

### 6.4 読解のコツ

#### 6.4.1 partial class の構成
Enumerable クラスは演算子ごとにファイル分割されている:
- `Where.cs`: Where 演算子
- `Select.cs`: Select 演算子
- `OrderBy.cs`: OrderBy/ThenBy 演算子
- 各ファイルが `partial class Enumerable` を宣言

#### 6.4.2 イテレータの型特化
同じ演算子でも入力型に応じた特化実装がある:
- `ArrayWhereIterator<T>`: 配列専用
- `ListWhereIterator<T>`: List<T>専用
- `IEnumerableWhereIterator<T>`: 汎用

#### 6.4.3 yield return の代替
LINQでは yield return の代わりに手動ステートマシン実装を使用:
- パフォーマンス向上
- 融合演算子の実現
- デバッグ情報の改善

### 6.5 関連ファイル一覧

| パス | 種別 | 役割 |
|------|------|------|
| `src/libraries/System.Linq/src/System/Linq/Enumerable.cs` | ソース | メインエントリーポイント |
| `src/libraries/System.Linq/src/System/Linq/Where.cs` | ソース | Where演算子 |
| `src/libraries/System.Linq/src/System/Linq/Select.cs` | ソース | Select演算子 |
| `src/libraries/System.Linq/src/System/Linq/OrderBy.cs` | ソース | ソート演算子 |
| `src/libraries/System.Linq/src/System/Linq/GroupBy.cs` | ソース | グループ化演算子 |
| `src/libraries/System.Linq/src/System/Linq/Join.cs` | ソース | 結合演算子 |
| `src/libraries/System.Linq/src/System/Linq/Sum.cs` | ソース | Sum集計 |
| `src/libraries/System.Linq/src/System/Linq/Count.cs` | ソース | Count演算子 |
| `src/libraries/System.Linq/src/System/Linq/First.cs` | ソース | First/FirstOrDefault |
| `src/libraries/System.Linq/src/System/Linq/Iterator.cs` | ソース | イテレータ基底クラス |
| `src/libraries/System.Linq/src/System/Linq/Lookup.cs` | ソース | Lookupクラス |
| `src/libraries/System.Linq/src/System/Linq/ThrowHelper.cs` | ソース | 例外スロー |

## 7. 使用例

### 7.1 基本的なクエリ

```csharp
var numbers = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

// 偶数のみ抽出して2乗
var result = numbers
    .Where(n => n % 2 == 0)
    .Select(n => n * n)
    .ToList();
// 結果: [4, 16, 36, 64, 100]
```

### 7.2 グループ化と集計

```csharp
var people = new[]
{
    new { Name = "Alice", Department = "Engineering", Salary = 80000 },
    new { Name = "Bob", Department = "Engineering", Salary = 90000 },
    new { Name = "Carol", Department = "Sales", Salary = 70000 }
};

var summary = people
    .GroupBy(p => p.Department)
    .Select(g => new
    {
        Department = g.Key,
        Count = g.Count(),
        AverageSalary = g.Average(p => p.Salary)
    })
    .ToList();
```

### 7.3 結合操作

```csharp
var orders = new[] { new { Id = 1, CustomerId = 101 }, new { Id = 2, CustomerId = 102 } };
var customers = new[] { new { Id = 101, Name = "Alice" }, new { Id = 102, Name = "Bob" } };

var joined = orders
    .Join(customers,
        order => order.CustomerId,
        customer => customer.Id,
        (order, customer) => new { order.Id, customer.Name })
    .ToList();
```

## 8. テスト観点

### 8.1 単体テスト観点
- 各演算子の正常系・異常系テスト
- 空シーケンス、単一要素、大量要素のテスト
- null入力に対する例外検証
- 遅延評価の動作確認

### 8.2 性能テスト観点
- 大規模データセットでのスループット
- メモリアロケーションの計測
- パイプライン長による影響測定

## 9. 変更履歴

| バージョン | 日付 | 変更内容 |
|------------|------|----------|
| 1.0 | 2026-01-30 | 初版作成 |
