CodeGym /コース /C# SELF /コレクション: OrderedDictionary<...

コレクション: OrderedDictionaryReadOnlySet

C# SELF
レベル 34 , レッスン 1
使用可能

1. コレクション OrderedDictionary

.NETは昔から標準ライブラリが超充実してるけど、プログラマー人生で「順番を覚えてる辞書が欲しい!」とか「変更できないユニークな値のセットが欲しい!」って時、ちょっと困ったことなかった?.NET 9より前はサードパーティのライブラリ使ったり、自作したり(GitHubからOrderedDictionaryコピペした人もいるよね…しーっ、内緒だよ)。

でも.NET 9からは新しい汎用コレクションが登場!もう変な工夫は不要!今回はその中でも特に使える2つ、OrderedDictionary<TKey, TValue>ReadOnlySet<T> を詳しく見ていこう。

1. OrderedDictionaryって何?

OrderedDictionaryは辞書とリストのハイブリッド。普通のDictionary<TKey, TValue>みたいに「キーと値」のペアを持つけど、追加した順番を絶対に守ってくれる。ユーザーが入力した順番でデータを処理したい時や、順番がビジネスロジックに影響する(レポート出力、データのシリアライズ、設定ファイルの生成とか)時に超便利!

たとえ話

普通の辞書は、物をどこに入れたか気にせずガンガン突っ込めるロッカーみたいなもの。でもOrderedDictionaryは、ちゃんと順番通りに並んでる引き出し付きの棚。何を最初に入れたか、次に何を入れたか、全部わかる!

2. Dictionaryとの主な違い

  • Dictionary: 要素の順番は保証されない(たまたま順番通りに見えても、それは幻だから信じちゃダメ!)。
  • OrderedDictionary: 追加した順番通りに要素が並ぶ。

3. シンタックスと主なメソッド

基本的な使い方はこんな感じ:


using System.Collections.Generic;

var od = new OrderedDictionary<string, int>();
od.Add("Ivan", 5);
od.Add("Svetlana", 8);
od.Add("Alex", 3);

// 追加した順番でループできる!
foreach (var pair in od)
{
    Console.WriteLine($"{pair.Key}: {pair.Value}");
}

出力:

Ivan: 5
Svetlana: 8
Alex: 3

同じ例を普通の辞書でやると、順番がバラバラになることが多い。でもOrderedDictionaryなら、絶対に追加した順番通り!

OrderedDictionaryは普通の辞書と同じインターフェースを実装してるよ:

  • IDictionary<TKey, TValue>
  • IReadOnlyDictionary<TKey, TValue>
  • IEnumerable<KeyValuePair<TKey, TValue>>

4. インデックスとキーでアクセスできる

特徴:OrderedDictionaryはキーだけじゃなく、インデックス(順番)でもアクセスできる!


// 名前(キー)でアクセス:
int svetlanaScore = od["Svetlana"]; // 8

// インデックスでアクセス:
var firstEntry = od.ElementAt(0); // KeyValuePair<string, int>("Ivan", 5)

5. 更新と削除

既存のキーで新しい要素を追加しようとすると例外が出る。値だけ変えたい時はインデクサを使おう:

od["Ivan"] = 10; // 既存の値を変更、順番はそのまま

削除はキーでもインデックスでもできるよ:


od.Remove("Svetlana");
od.RemoveAt(0);      // "Ivan"を削除

6. 構造のイメージ


flowchart LR
    A("0: Ivan - 5")
    B("1: Svetlana - 8")
    C("2: Alex - 3")
    A --> B --> C
各ノードはキーと値のペアで、矢印は追加した順番を示してるよ。

7. よくある落とし穴と注意点

多くの開発者がDictionary<TKey, TValue>で順番を期待しちゃうけど、それは罠!データによっては順番が保たれることもあるけど、.NETのバージョンやプラットフォームが変わると一気に崩れるよ。

OrderedDictionaryは順番を保持する分、挿入や途中削除がちょっとだけ遅いけど、ほとんどのケースではメリットの方が大きい!

インデックスでよく探すならOrderedDictionary、キーだけで高速検索したい&順番どうでもいいなら普通の辞書を使おう。

8. アプリでの実用例

例えば、社員と部署を管理するアプリで、社員を追加した順番でレポートを出したい時:


var employeeScores = new OrderedDictionary<string, int>();
employeeScores.Add("Петр", 100);
employeeScores.Add("Анна", 150);
employeeScores.Add("Виктория", 80);

// レポートはいつも追加順で出力できる!
foreach (var pair in employeeScores)
{
    Console.WriteLine($"{pair.Key}: {pair.Value} バロフ");
}

2. コレクション ReadOnlySet<T>

1. ReadOnlySetって何?

ReadOnlySet<T>は変更できない(immutable)ユニークな値のセット。前は「読み取り専用のset」が欲しい時、.ToHashSet()でコピーしたり、自作ラッパーを作ったりしてた。でも今は、一度作ったら追加も削除もできないコレクションがある!これでコードの安全性が上がるし、外部からうっかりデータを変えられる事故も防げるよ。

たとえ話

これは、ユニークな名前を書き込んだノートをラミネートしちゃった感じ。もう誰も書き足せないし、破ったり修正もできない!

2. ReadOnlySetの作り方

一番簡単なのは拡張メソッドを使う方法:


var colors = new[] { "Red", "Green", "Blue", "Green" };
var readOnlyColors = colors.ToReadOnlySet();

// ここにはユニークな値だけ、しかも変更不可!
foreach (var color in readOnlyColors)
    Console.WriteLine(color);

出力:

Red
Green
Blue

直接コンストラクタを使うこともできる(必要なら):


var set = new ReadOnlySet<int>(new[] {1, 2, 2, 3, 5, 1}); // 結局1,2,3,5だけ

Microsoft DocsのReadOnlySet

3. 主なプロパティとメソッド

  • 読み取り専用(immutable)
  • Count ― 要素数
  • Contains(item) ― 要素があるかチェック
  • LINQクエリ対応(IEnumerable<T>
  • 検索は速いけど、追加・削除・クリアはできない

例:


if (readOnlyColors.Contains("Red"))
    Console.WriteLine("赤はリストにあるよ!");

こういうのはできない:


// コンパイルエラー!
readOnlyColors.Add("Yellow");

4. どんな時に使う?

外部にセットを渡したいけど、誰にも中身を変えてほしくない時に超便利。例えば:

  • サポートしてるユーザー権限の一覧を返す
  • 許可されたファイル拡張子のリスト
  • 絶対に変えちゃいけない設定パラメータの一覧

アプリの例:許可された部署の一覧があるとする:


public static ReadOnlySet<string> Departments { get; } =
    new[] { "カドリ", "ラズラボトカ", "ブハルテリア" }.ToReadOnlySet();

これで外部から部署リストを勝手に変えられる心配なし!

5. イメージ図:普通のHashSetとの違い


graph LR
    A[HashSet] -- Add/Remove/Contains --> B((Elements))
    C[ReadOnlySet] -- Only Contains --> D((Elements))
HashSetは変更できるけど、 ReadOnlySetは絶対に変更不可!

3. OrderedDictionary vs. ReadOnlySet: 違いまとめ表

コレクション ペアを持つ? 順番保証 変更できる キー検索 インデックス検索 用途例
OrderedDictionary はい「キー-値」 はい はい はい はい マップ、設定、レポート
ReadOnlySet いいえ、値だけ いいえ いいえ はい いいえ 安全なセット、定数
HashSet いいえ、値だけ いいえ はい はい いいえ 変更が必要なセット
Dictionary はい「キー-値」 いいえ はい はい いいえ 順番不要なマップ
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION